How to Make This Jbutton Visible? When I Have Progressive Scan Background Jwindow()

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.

Sample Image

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



Leave a reply



Submit