How can I make this JButton visible? When I have progressive scan background JWindow()?
It's not clear how your video source works, but it appears to be incompatible with Swing due to Mixing Heavyweight and Lightweight Components. Although awt
components aren't transparent, you can always draw your own translucent text on the Frame
and do manual hit testing, as suggested below. You might also check to see if your video source API supports Double Buffering and Page Flipping.
import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Rectangle2D;
/** @see http://stackoverflow.com/questions/6725618 */
public class AlphaFrame extends Frame {
private static final Font font = new Font("Dialog", Font.BOLD, 24);
private float alpha = 1f;
private Rectangle rect = new Rectangle();
public static void main(String[] args) {
AlphaFrame af = new AlphaFrame();
af.setTitle("Translucent Button");
af.setAlpha(0.5f);
af.setForeground(Color.green);
af.setBackground(Color.black);
af.setVisible(true);
}
public AlphaFrame() {
this.setSize(320, 240);
this.setLocationRelativeTo(null);
this.setBackground(Color.white);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (rect.contains(e.getPoint())) {
System.out.println("Pressed.");
}
}
});
repaint();
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha));
g2.setColor(getForeground());
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics();
String s = getTitle();
Insets i = getInsets();
int dx = i.left + 10;
int dy = i.top + fm.getHeight() + 10;
Rectangle2D bounds = fm.getStringBounds(s, g);
rect.x = dx + (int) bounds.getX() - 1;
rect.y = dy + (int) bounds.getY() - 1;
rect.width = (int) bounds.getWidth() + 1;
rect.height = (int) bounds.getHeight() + 1;
System.out.println(i + " \n" + bounds + "\n" + rect);
g2.drawRect(rect.x, rect.y, rect.width, rect.height);
g2.drawString(s, dx, dy);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
}
}
Creating custom JButton from images containing transparent pixels
Since there were good elements in multiple answers, but none of the answers were complete on their own, I'll answer my own question so other people that have the same problem can try something similar.
I created my buttons using a new class which extends JButton, with a new constructor that takes a BufferedImage as parameter instead of an icon. The reason for that is that when I did something like myButton.getIcon(), it would return an Icon, then I'd have to make various manipulations on it to make it a BufferedImage of the right size, and it ended up not working anyway because it seems like the first cast to Icon made it lose the alpha data in the pixels, so I couldn't check to see if the user was clicking on transparent pixels or not.
So I did something like this for the constructor:
public class MyButton extends JButton
{
private BufferedImage bufImg;
public MyButton(BufferedImage bufImg)
{
super(new ImageIcon(bufImg));
this.bufImg = bufImg;
}
}
Then I created an accessor for my bufImg that resized the image to fit the JButton using the getSize() method and then returned an image resized at the right size. I do the transformations in the getBufImg() accessor because the image size might change when the window gets resized. When you call the getBufImg(), it's usually because you clicked on the button and thus you're not currently resizing the window.
Something a little bit like this will return the image at the right size:
public BufferedImage getBufImg()
{
BufferedImage newImg = new BufferedImage(getSize().getWidth(), getSize().getHeight(), BufferedImage.TYPE_INT_ARGB); //Create a new buffered image the right size
Graphics2D g2d = newImg.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(bufImg, 0, 0, getSize().getWidth(), getSize().getHeight(), null);
g2d.dispose();
return newImg;
}
With that buffered image, you can then code a method like this:
private int clickAlphaValue(BufferedImage bufImg, int posX, int posY)
{
int alpha;
alpha = (bufImg.getRGB(posX, posY) >>24) & 0x000000FF; //Gets the bit that contains alpha information
return alpha;
}
That you call on the button that implements a MouseListener, like this:
myButton.addMouseListener(new MouseListener()
{
public void mouseClicked(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
if(clickAlphaValue(((myButton)e.getSource()).getBufImg(), e.getX(), e.getY()) != 0) //If alpha is not set to 0
System.exit(0); //Or other things you want your button to do
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
});
And voila! The button will only do the action if you clicked on non-transparent pixels.
Thanks for the help everyone, I couldn't have come up with this solutions on my own.
How to make the AWT component transparent on progressive background image? Used Window(), Panel(), Button() but failed
This is your second question on this topic and I still can't tell what you are doing. You keep talking about a background image, but no where in your code do you show the code for the image.
Yes there are problems when you use setColor with an alpha value of 0. You should NOT do this. The proper solution is to just make the component non-opaque.
See Background With Transparency for more information.
Or maybe Background Panel is what you are looking for.
Also you usage of constraints is old:
this.add("North", button);
First of all you should not hard code the constraint value. Secondly if you read theAPI you will see that you should be using:
this.add(button, BorderLayout.NORTH);
and when using layout managers you don't set the size and location.
Add subtitle and basic operation panel in VLCJ @ Java
To set an external subtitle file:
mediaPlayerComponent.getMediaPlayer().setSubTitleFile("whatever.srt");
How you add a pause/play button is entirely up to you, it requires standard Swing code that is not particular to vlcj. You add buttons to your user interface, and link those buttons up with the media player by using event listeners. For example, this is one way:
JButton playButton = new JButton("Play/Pause");
playButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
mediaPlayerComponent.getMediaPlayer.pause();
}
});
There are numerous reasons why the native library might not be found, but NativeLibrary.addSearchPath(...) certainly does work. You have to be sure you match the CPU architectures of your JVM and your VLC installation (32-bit JVM requires 32-bit VLC, 64-bit JVM requires 64-bit VLC). In most cases you should just use:
new NativeDiscovery().discover();
There are a whole bunch of step-by-step tutorials at http://capricasoftware.co.uk/#/projects/vlcj/tutorial
Java paintComponent override differences between versions 5 and 6
Create a copy of the Graphics context in the paintComponent function. This will fix the problem.
public void paintComponent( Graphics g )
{
super.paintComponent( g );
Graphics2D g2 = (Graphics2D) g.create();
...
}
Transparent AWT component, possible?
AFAIK not possible correctly for prehistoric AWT Container and Components
you can to try that with changing this code from Swing to the AWT, Translucency is supported for Swing JComponents
only
Text Overlay on JPanel
One way to do this with vlcj is to use the "marquee".
The marquee is provided by native LibVLC library functions, wrapped by vlcj.
First:
import static uk.co.caprica.vlcj.player.Marquee.marquee;
Then in your mouse click listener:
marquee()
.text("Play")
.location(x, y)
.position(libvlc_marquee_position_e.bottom)
.opacity(0.7f)
.colour(Color.white)
.timeout(5000)
.size(20)
.apply(mediaPlayer);
This is a "builder" style of API, there is another API with individual methods for the marquee, e.g.:
mediaPlayer.setMarqueeText("Play");
mediaPlayer.setMarqueeSize(60);
mediaPlayer.setMarqueeOpacity(70);
mediaPlayer.setMarqueeColour(Color.green);
mediaPlayer.setMarqueeTimeout(3000);
mediaPlayer.setMarqueeLocation(300, 400);
mediaPlayer.enableMarquee(true)
All of this is documented in the vlcj Javadoc:
http://caprica.github.io/vlcj/javadoc/3.0.0/uk/co/caprica/vlcj/player/Marquee.html
http://caprica.github.io/vlcj/javadoc/3.0.0/uk/co/caprica/vlcj/player/MediaPlayer.html
There are other ways...
You can try overlaying an AWT Label with absolute positioning on top of the video, this will work but the label will not have a transparent background.
You can use the so-called "direct" rendering media player (where you render the video yourself) and then you can paint your own graphics on top of the video, or use a Swing JLabel. In this case you can use transparency.
You could even overlay a transparent top-level window on top of your video window and paint/put your label in that window.
All of these approaches are demonstrated in the various examples in the vlcj test sources. There are test examples for marquee, and lightweight and heavyweight overlays.
But using the marquee is the simplest and therefore recommended way.
Selecting Text within Graphics / Graphics2D
How do I select text from a string using the mouse when it's rendering in Graphics?
Add a MouseListener
and when it fires, check if it within the bounds of the String
.
Ways to check the bounds of a String
:
FontMetrics
GlyphVector
e.g.
Circle enemy detection in TD game
Both java.awt.Rectangle
and java.awt.geom.Ellipse2D
implement the Shape
interface. The latter's contains()
method may be useful.
Related Topics
Double Decimal Formatting in Java
When to Use Stringbuilder in Java
How to Parse a Dynamic JSON Key in a Nested JSON Result
Any Good Orm Tools for Android Development
Android How to Draw a Smooth Line Following Your Finger
Difference Between Using Java.Library.Path and Ld_Library_Path
How to Run Java Application on Startup of Ubuntu Linux
Too Many Open Files Error But Lsof Shows a Legal Number of Open Files
Find Native Memory Leak in Java Application Using Jemalloc
How to Parse Dates in Multiple Formats Using Simpledateformat
Find Where Java Class Is Loaded From
Android Listview Selected Item Stay Highlighted
How to Check If an App Running on Android
Foreign Key Constraints in Android Using SQLite? on Delete Cascade
How to Get Unique Random Product in Node Firebase
Setting/Changing the Ctime or "Change Time" Attribute on a File