Jbutton() Only Working When Mouse Hovers

JButton() only working when mouse hovers

Likely you have a layout problem where you're trying to add JButtons with absolute bounds into a container that uses a non-null layout manager. Suggestions

  • Do not use setBounds and absolute positioning to size and place your components.
  • Read up on and use the layout managers to do this heavy lifting for you: Lesson: Laying Out Components Within a Container
  • Don't forget to call pack() on your JFrame after adding all components
  • Call setVisible(true) after calling pack() and again call both only after adding all components to your GUI.
  • A null layout is available if you absolutely need to use absolute positioning of components, but regardless, you should strive to avoid using it.

JButtons only appear when mouse hover over them

Problems:

  • You're using a null layout-using JPanel to hold JButtons in a JScrollPane which will make the scroll pane fail in its ability to show scroll bars and scroll effectively
  • You add components into a container (the same JPanel above) without telling the GUI to repaint the container, and so the components, the added JButtons, don't display. This latter is fixed by calling jpFullofButtons.repaint(); after adding components to the JPanel -- but the JScrollPane still won't work right

Better to use a decent layout manager, here perhaps a GridLayout, and call revalidate() and repaint() on the container, the jpFullofButtons JPanel, after adding components to it.

Side note about your MRE attempt: it's almost there, but you still left in the DAO requirement as well as an undefined class, DataVO, preventing us from coping, pasting, and running your code.

My MRE example:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.text.NumberFormat;
import java.util.Locale;
import javax.swing.*;

@SuppressWarnings("serial")
public class JButtonsShowUp extends JPanel {
private JButton reAddButtonsBtn = new JButton("Re-Add Buttons");
private JPanel jpFullofButtons = new JPanel(new GridLayout(0, 1));
private JScrollPane jsp = new JScrollPane(jpFullofButtons);

public JButtonsShowUp() {
reAddButtonsBtn.addActionListener(e -> reAddButtons());
JPanel topPanel = new JPanel();
topPanel.add(reAddButtonsBtn);

jsp.setPreferredSize(new Dimension(385, 450));

int gap = 20;
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(jsp, BorderLayout.CENTER);
}

private void reAddButtons() {
jpFullofButtons.removeAll();
int max = 100;
for (int i = 0; i < max; i++) {
String randomText = "";
for (int j = 0; j < 5; j++) {
char c = (char) ('a' + (int) (26 * Math.random()));
randomText += c;
}

double randomPrice = 10 + 20 * Math.random();
final DataVO2 data = new DataVO2(randomText, randomPrice);

String text = String.format("Text: %s%02d, Price: $%1.2f", randomText, i, randomPrice);
JButton button = new JButton(text);
button.addActionListener(e -> buttonAction(data));
jpFullofButtons.add(button);
}
jpFullofButtons.revalidate();
jpFullofButtons.repaint();

}

private void buttonAction(DataVO2 data) {
System.out.println("Button pressed: " + data);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JButtonsShowUp mainPanel = new JButtonsShowUp();

JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}

}

class DataVO2 {
private NumberFormat priceFormat = NumberFormat.getCurrencyInstance(Locale.US);
private String name;
private double price;

public DataVO2(String name, double price) {
this.name = name;
this.price = price;
}

public String getName() {
return name;
}

public double getPrice() {
return price;
}

@Override
public String toString() {
String priceText = priceFormat.format(price);
return "DataVO2 [name=" + name + ", price=" + priceText + "]";
}

}

JButtons Only Working When Mouse Hovers Over

Since you override paint you need to call super.paint(g); as the first line.

public void paint(Graphics g) {
super.paint(g); // <-- add this.
g.drawString("Under Construction...", 240, 250);
}

Also, you should move your logic off the main() thread; like

SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Main();
}
});

Components appear only when mouse hovers over them

This seems to work better.

  • I fixed radiobutton and checkbox positions.

  • I used different references for checkbox and radiobutton objects (r1, r2, chk1, chk2, chk3)

  • I added a buttongroup for radiobuttons.

     import java.awt.Color;
    import java.awt.Container;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;

    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.JTextField;

    import javax.swing.ButtonGroup;

    public class JFrameBackground extends JFrame implements ActionListener
    {

    private static final long serialVersionUID = 1L;

    JLabel l1,l2,l3,l4;
    JTextField t1;
    JButton b1;
    JRadioButton r1, r2;
    JComboBox com1;
    JCheckBox chk1, chk2, chk3;

    JPanel p2;
    JButton b;

    public JFrameBackground()
    {

    p2=new JPanel();
    p2.setLayout(null);
    p2.setBounds(250, 0, 400, 400);
    add(p2);

    l1 = new JLabel("Name:");
    l1.setBounds(100,10,70,30);
    p2.add(l1);

    t1 = new JTextField();
    t1.setBounds(100,50,70,30);
    p2.add(t1);

    l2 = new JLabel("Gender:");
    l2.setBounds(100,130,70,30);
    p2.add(l2);

    r1 = new JRadioButton("Male");
    r1.setBounds(100,150,70,30);
    p2.add(r1);

    r2 = new JRadioButton("Female");
    r2.setBounds(180,150,70,30);
    p2.add(r2);

    ButtonGroup bg=new ButtonGroup();
    bg.add(r1);
    bg.add(r2);

    l3 = new JLabel("Course:");
    l3.setBounds(100,180,70,30);
    p2.add(l3);

    chk1= new JCheckBox("Bca");
    chk1.setBounds(100, 200, 70, 30);
    p2.add(chk1);

    chk2= new JCheckBox("BBA");
    chk2.setBounds(180, 200, 70, 30);
    p2.add(chk2);

    chk3= new JCheckBox("BCOM");
    chk3.setBounds(260, 200, 70, 30);
    p2.add(chk3);

    l4 = new JLabel("Country:");
    l4.setBounds(100,220,70,30);
    p2.add(l4);

    String name[] = {"India","USA","UK","Rus"};

    com1=new JComboBox(name);
    com1.setBounds(100, 250, 70, 30);
    p2.add(com1);

    b1= new JButton("Submit");
    b1.setBounds(140, 300, 90, 30);
    p2.add(b1);

    b =new JButton("Show form");
    b.setBounds(0, 4, 190, 40);
    b.setFocusPainted(false);
    b.setBorderPainted(false);
    b.addActionListener(this);
    getContentPane().add(b);

    b.addMouseListener(new MouseAdapter()
    {
    public void mouseClicked(MouseEvent me)
    {

    p2.setVisible(true);

    }
    });

    Container c=getContentPane();
    c.setBackground(Color.gray);
    setBounds(170, 100, 1250, 500);

    setLayout(null);
    setVisible(true);
    }

    public static void main(String[] args)
    {

    new JFrameBackground();

    }

    public void actionPerformed(ActionEvent arg0)
    {

    }

    }

JButton only show up on mouseover

Swing uses a "layering" concept for it's painting...

paint calls paintComponent, paintBorder and paintChildren. By overriding paint and failing to call super.paint, you've prevented the component from painting it's various layers.

In Swing, it is preferred to use paintComponent to provide custom painting, which allows you to paint underneath any other components that might be added to the component.

Sample Image

public class TestPaint01 {

public static void main(String[] args) {
new TestPaint01();
}

public TestPaint01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}

JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

}
});
}

public class TestPane extends JPanel {

private Image backgroundImage;

public TestPane() {
try {
BufferedImage background = ImageIO.read(new File("/path/to/image.jpg"));
//backgroundImage = background.getScaledInstance(-1, background.getHeight() / 4, Image.SCALE_SMOOTH);
backgroundImage = background;
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
add(new JButton("Hello"));
}

@Override
public Dimension getPreferredSize() {
return backgroundImage == null ? super.getPreferredSize() : new Dimension(backgroundImage.getWidth(this), backgroundImage.getHeight(this));
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (getWidth() - backgroundImage.getWidth(this)) / 2;
int y = (getHeight() - backgroundImage.getHeight(this)) / 2;
g.drawImage(backgroundImage, x, y, this);
}

}

}

You might find A Closer look at the Paint Mechanism and Painting in AWT and Swing informative.

Button and JSlider only appear when I hover the screen

What i would do:

Add a MouseMotionListener to the panel:

jp.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {

}

@Override
public void mouseMoved(MouseEvent e) {
System.out.println("motion" + e.getPoint());
}
});

Add a ChangeListener to the penSize:

penSize.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
System.out.println("new pensize: " + penSize.getValue());
}
});

And so on. So you have add the lsiteners to the components and not to the frame.

I hope to have helped you for now. If you have any questions, please post a minimal reproducible example as Andrew wrote.

Steffi



Related Topics



Leave a reply



Submit