5

How can I make the JButton visible?

1) When no progressive background is turned on: JButton is showing

enter image description here

2) When no progressive background is turned on, JButton is pressed still showing no flicker:

enter image description here

3) When progressive background is turned on, JButton is invisible and on pressing in this I see flicker and JButton() appears and again hides auto. << Problem is here, so how can I fix it?

enter image description here

import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Graphics;
import javax.swing.*;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class ButtonTest extends JWindow implements MouseListener, MouseMotionListener {

    private static final long serialVersionUID = 1L;
    private JFrame frame = new JFrame();
    private SoftJButton softButton1;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ButtonTest j = new ButtonTest();
                j.createAndShowGUI();
            }
        });
    }

    public void createAndShowGUI() {
        softButton1 = new SoftJButton("Transparent Button");
        softButton1.setBackground(Color.GREEN);
        softButton1.setAlpha(0.5f);
        softButton1.setDoubleBuffered(true);
        this.setLayout(new BorderLayout());
        this.setBounds(100, 30, 200, 100);
        this.setBackground(new Color(0, 0, 0, 255));
        this.setVisible(true);
        add(softButton1);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
    }

    public void mouseDragged(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseMoved(MouseEvent e) {
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public static class SoftJButton extends JButton {

        private static final JButton lafDeterminer = new JButton();
        private static final long serialVersionUID = 1L;
        private boolean rectangularLAF;
        private float alpha = 1f;

        public SoftJButton() {
            this(null, null);
        }

        public SoftJButton(String text) {
            this(text, null);
        }

        public SoftJButton(String text, Icon icon) {
            super(text, icon);
            setOpaque(false);
            setFocusPainted(false);
        }

        public float getAlpha() {
            return alpha;
        }

        public void setAlpha(float alpha) {
            this.alpha = alpha;
            repaint();
        }

        @Override
        public void paintComponent(java.awt.Graphics g) {
            java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
            if (rectangularLAF && isBackgroundSet()) {
                Color c = getBackground();
                g2.setColor(c);
                g.fillRect(0, 0, getWidth(), getHeight());
            }
            super.paintComponent(g2);
        }

        @Override
        public void updateUI() {
            super.updateUI();
            lafDeterminer.updateUI();
            rectangularLAF = lafDeterminer.isOpaque();
        }
    }
}
Charles Goodwin
  • 6,402
  • 3
  • 34
  • 63
  • It's good to see the end (hopefully) of those NNN class names. Now if you could post an [SSCCE](http://pscode.org/sscce.html), that would be ideal! – Andrew Thompson Jul 17 '11 at 17:53
  • Yeah, you can still abbreviate names without resorting to single letter variables. – Chris Dennett Jul 17 '11 at 18:15
  • what are you meaning with `When progressive background is truned on` – mKorbel Jul 17 '11 at 18:39
  • 1
    Again I have to ask, what part about posting a SSCCE don't you understand??? It is not up to us to comment out code. It is up to you to post code that we can copy and paste and compile and execute. This is your 5th question on this topic. Why is it so hard for you to understand this simple concept??? – camickr Jul 17 '11 at 18:45
  • buuump by reading &camickr post .... are you tried use a JLabel instead of JButton, JLabel (with half size funcionalities JPanel too) – mKorbel Jul 17 '11 at 18:51
  • " It reloads a camera live image (20 frames per second)," I don't have access to your video camera software and I'm guessing others in the forum don't either. So is the problem the software or your code? Your question is about dynamically changing the background image of a panel that contains a transparent button. So create a SSCCE that does this. You can simulate your video camera by using a Swing Timer to dynamcally change an image on the JWindow. Then we will all be able to download and test your code. – camickr Jul 17 '11 at 19:07
  • hmmm then you have to start with this code, better I cann't see arount, http://stackoverflow.com/questions/2163544/re-paint-problem-on-translucent-frame-panel-component – mKorbel Jul 17 '11 at 19:21
  • The example has no JLabel in the code, so I don't know what you are talking about. – camickr Jul 17 '11 at 19:21
  • 2
    @camickr,@mKorbel: please see here this way of Timer and background overflow does not kill Swing, but it do get killed when using real webcam to jWindow. e.g: https://gist.github.com/1087947 –  Jul 17 '11 at 19:32
  • Quit posting code all over the web!!! Your question was asked here so all the information needed to solve the problem should be posted here. If the webcam doesn't work then the problem is the way the webcam paints to the JWindow. It would appear it is not designed to have components painted on top if it. Unless you can post an actual SSCCE that demonstrates the problem, I'm outta here. I've already wasted too much time. – camickr Jul 17 '11 at 19:50
  • I already suggested the problem is how the SDK interacts with Swing. If that is the problem we can't change that and you are out of luck. Maybe you can demonstrate the problem by simulating what you think the SDK is doing. Basically, it needs to repaint an image at a specified refresh rate. Naybe you can simulate this by using a Timer to keep repainting the image. If you can duplicate the problem then you have a SSCCE. If you can't simulate the problem then I can't help. Are you using JDK6_17 or later? AWT/Swing components work better together in those versions. – camickr Jul 17 '11 at 20:29
  • 2
    @camickr: This one: java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03), Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode) –  Jul 17 '11 at 20:58
  • @camickr problem with Alpha and GPU performance, just by using basic JComponents (size 800x600), there is about JButton because returns hight level GPU performance for repainting its compound GradientPaints, I can see flickering, partial repaint freeze (i5, Xp, nvidia240, JDK6.20), see my attn. code – mKorbel Jul 17 '11 at 21:09

2 Answers2

4

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.

enter image description here

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;
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • thank you. I tested your code with web cam dump to AlphaFrame af = new AlphaFrame(); and i see my camera is capturing but your GUI is showing only without any transparency. –  Jul 26 '11 at 09:39
  • I don't know your source's API; I'm guessing you'll have to override it's `paint()` method to add the translucent layer. – trashgod Jul 26 '11 at 15:23
  • its a closed source SDK (commercial license) which allow me to only use in my local PC. Which i can not override using paint() method. Only i can do such as: thirdpartySDK.windowID(my JWindow or Window or Frame or Canvas or JFrame); Then it start the webcam capture. When it start no transparency of Java works. I tried your example and also other examples all ended with no luck. –  Jul 27 '11 at 16:32
  • Can't you override `paint()` (or `paintComponent()`, as appropriate) in the `Component` you pass as a parameter to `thirdpartySDK.windowID()`? – trashgod Jul 27 '11 at 18:27
  • No, its a compiled code only which accepting as Element. e.g: public void setWindowID(long handle) { //compiled code throw new RuntimeException("Compiled Code"); } –  Jul 30 '11 at 15:57
1
import java.awt.event.*;
import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;

public class ButtonTest {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ButtonTest().createAndShowGUI();
            }
        });
    }
    private JFrame frame;
    private SoftJButton softButton1;

    public void createAndShowGUI() {
        softButton1 = new SoftJButton("Transparent Button");
        softButton1.setPreferredSize(new Dimension(800, 600));
        frame = new JFrame();
        frame.add(softButton1);
        frame.setLocation(150, 150);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        Timer alphaChanger = new Timer(30, new ActionListener() {

            private float incrementer = -.03f;

            @Override
            public void actionPerformed(ActionEvent e) {
                float newAlpha = softButton1.getAlpha() + incrementer;
                if (newAlpha < 0) {
                    newAlpha = 0;
                    incrementer = -incrementer;
                } else if (newAlpha > 1f) {
                    newAlpha = 1f;
                    incrementer = -incrementer;
                }
                softButton1.setAlpha(newAlpha);
            }
        });
        alphaChanger.start();
        Timer uiChanger = new Timer(5500, new ActionListener() {

            private LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
            private int index = 1;

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    UIManager.setLookAndFeel(laf[index].getClassName());
                    SwingUtilities.updateComponentTreeUI(frame);
                } catch (Exception exc) {
                    exc.printStackTrace();
                }
                index = (index + 1) % laf.length;
            }
        });
        uiChanger.start();
    }

    public static class SoftJButton extends JButton {

        private static final JButton lafDeterminer = new JButton();
        private static final long serialVersionUID = 1L;
        private boolean rectangularLAF;
        private float alpha = 1f;

        public SoftJButton() {
            this(null, null);
        }

        public SoftJButton(String text) {
            this(text, null);
        }

        public SoftJButton(String text, Icon icon) {
            super(text, icon);

            setOpaque(false);
            setFocusPainted(false);
        }

        public float getAlpha() {
            return alpha;
        }

        public void setAlpha(float alpha) {
            this.alpha = alpha;
            repaint();
        }

        @Override
        public void paintComponent(java.awt.Graphics g) {
            java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
            if (rectangularLAF && isBackgroundSet()) {
                Color c = getBackground();
                g2.setColor(c);
                g.fillRect(0, 0, getWidth(), getHeight());
            }
            super.paintComponent(g2);
        }

        @Override
        public void updateUI() {
            super.updateUI();
            lafDeterminer.updateUI();
            rectangularLAF = lafDeterminer.isOpaque();
        }
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 1
    yes flicking, and all buttons are gone when i apply the Web cam on it. And on mouse over to the window, gives flicking. –  Jul 17 '11 at 21:22
  • @89899.3K http://processing.org/reference/libraries/video/index.html and some of Gurus (I forgot who) is member of – mKorbel Jul 17 '11 at 21:46
  • 2
    >>>>>>>This code is tested for verification<<<<<<<<<. But it does not solve the problem. Swing GUI is for lightweight task. But my case is heavy weight where Video gets loaded in the main Frame(). –  Jul 21 '11 at 12:52