ssoTheNewb
ssoTheNewb

Reputation: 13

JButtons only appear when mouse hover over them

I have a problem (could be more than one..) with my project. JButton components only show up when I hover the mouse over them.

My project, basically, is taking data from MySQL and setting it on buttons.

For example:

and so on...

Buttons are on JPanel which is in a JScrollPane. (I did this on purpose as data can not be fit in one panel without scroll and when I click the the button, a new window relating to the info on the clicked button have to pop up)

And I added an ActionListener on another button set which are 'category' buttons(chicken, pizza) to put data on the buttons I mentioned above. When the category button is clicked, data according to the category is extracted and set on buttons one by one.

I searched many times to solve the problem, but I couldn't find the answer. Just assuming, it happened because I used setLayout(null) all over, or because buttons are added after the main frame is set visible.

It's good to solve the problem but I, more importantly, want to know the reason why.

Please help me to find the cause of this problem so that I don't make the same error next time and avoid bad practices!

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class JbuttonNotShowUp extends JFrame implements ActionListener {
    JButton chicken, pizza;
    JButton[] jbtnArray;
    JPanel jp, jpFullofButtons;
    JScrollPane jsp;

    public JbuttonNotShowUp() {

        jp = new JPanel();
        jp.setLayout(null);

        jpFullofButtons = new JPanel();
        jpFullofButtons.setLayout(null);

        jsp = new JScrollPane(jpFullofButtons, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        chicken = new JButton("chicken");
        pizza = new JButton("pizza");

        jp.setBounds(0, 0, 440, 650);

        chicken.setBounds(25, 80, 61, 35);
        pizza.setBounds(90, 80, 61, 35);

        jsp.setBounds(25, 140, 385, 450);

        chicken.addActionListener(this);
        pizza.addActionListener(this);

        jp.add(jsp);
        jp.add(chicken);
        jp.add(pizza);
        add(jp);

        setBounds(0, 0, 450, 650);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        JbuttonNotShowUp f = new JbuttonNotShowUp();
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        JButton jbutton = (JButton) e.getSource();

        jpFullofButtons.removeAll();

        DataDAO dao = new DataDAO();
        ArrayList<DataVO> list = dao.dataExtract(jbutton.getText());

        jbtnArray = new JButton[list.size()];

        int y = 0;
        for (int i = 0; i < list.size(); i++) {
            jbtnArray[i] = new JButton(
                    list.get(i).getName() + "," + list.get(i).getPrice() + "," + list.get(i).getDescription());
            jbtnArray[i].setSize(390, 50);
            jbtnArray[i].setLocation(0, y);
            jbtnArray[i].addActionListener(this);
            jpFullofButtons.add(jbtnArray[i]);
            y += 50;
        }

    }
}

Upvotes: 1

Views: 1804

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285440

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 + "]";
    }
    
}

Upvotes: 1

Related Questions