JButtons появляются только при наведении на них указателя мыши.

У меня проблема (может быть больше одной) с моим проектом. JButton компоненты отображаются только при наведении на них курсора мыши.

Мой проект, по сути, берет данные из MySQL и устанавливает их на кнопки.

Например:

  • 'Ааа', 1000, 'алфавит' на кнопке j[0]
  • 'Bbb', 50, 'алфавит2' на кнопке j[1]

и так далее...

Кнопки находятся на JPanel, который находится в JScrollPane. (Я сделал это специально, так как данные не могут быть размещены на одной панели без прокрутки, и когда я нажимаю кнопку, должно появиться новое окно, относящееся к информации о нажатой кнопке)

И я добавил ActionListener к другому набору кнопок, которые являются кнопками «категории» (курица, пицца), чтобы поместить данные на кнопки, о которых я упоминал выше. При нажатии кнопки категории данные в соответствии с категорией извлекаются и устанавливаются на кнопки одна за другой.

Я искал много раз, чтобы решить проблему, но я не мог найти ответ. Просто предположим, что это произошло из-за того, что я использовал setLayout(null) повсюду, или из-за того, что кнопки добавляются после того, как основной фрейм становится видимым.

Хорошо решить проблему, но я, что более важно, хочу знать причину.

Пожалуйста, помогите мне найти причину этой проблемы, чтобы я не совершал ту же ошибку в следующий раз и избегал плохих практик!

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;
        }

    }
}

Вы уже знаете, что не должны использовать нулевые макеты, так зачем вы их используете? Шутки в сторону?

Hovercraft Full Of Eels 09.04.2022 20:38

Далее, если вы хотите быстро получить полный полный ответ, лучше опубликовать действительный минимальный воспроизводимый пример. Ссылка в основном объяснит, что это такое, но если у вас есть вопросы по этому поводу, пожалуйста, прокомментируйте.

Hovercraft Full Of Eels 09.04.2022 20:42

Это командный проект, и моя команда хочет спроектировать... и было невозможно сделать макет, так как моя команда не хочет использовать нулевой макет для меня.

ssoTheNewb 09.04.2022 20:42

Спасибо за обновление, но, пожалуйста, сообщите тому, кто принял это решение, что это глупо и опасно и приведет к бесконечным головным болям, особенно когда вы хотите обновить или изменить графический интерфейс, визуализировать его в других системах или использовать графический интерфейс с JScrollPane. Это приведет к бесконечным проблемам. Но опять же, лучше всего изолировать проблему от незадействованного кода с приличным минимальный воспроизводимый пример.

Hovercraft Full Of Eels 09.04.2022 20:44

Спасибо, что сообщили мне о минимальном воспроизведении, я проверю!

ssoTheNewb 09.04.2022 20:46
"моя команда не хочет использовать макет" Затем попросите их решить проблемы, явно вызванные использованием макета null. Возможно, после трех дней борьбы с проблемой они поймут, что могли бы (правильно) организовать графический интерфейс с помощью макетов за два дня (или меньше).
Andrew Thompson 09.04.2022 21:25
Основы программирования на Java
Основы программирования на Java
Java - это высокоуровневый объектно-ориентированный язык программирования, основанный на классах.
Концепции JavaScript, которые вы должны знать как JS программист!
Концепции JavaScript, которые вы должны знать как JS программист!
JavaScript (Js) - это язык программирования, объединяющий HTML и CSS с одной из основных технологий Всемирной паутины. Более 97% веб-сайтов используют...
1
6
40
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблемы:

  • Вы используете нулевой макет, используя JPanel для удержания JButtons в JScrollPane, что приведет к сбою панели прокрутки в ее способности отображать полосы прокрутки и эффективно прокручивать
  • Вы добавляете компоненты в контейнер (тот же JPanel выше), не сообщая графическому интерфейсу о перерисовке контейнера, поэтому компоненты, добавленные JButtons, не отображаются. Это последнее исправляется вызовом jpFullofButtons.repaint(); после добавления компонентов в JPanel -- но JScrollPane по-прежнему не будет работать правильно.

Лучше использовать приличный менеджер компоновки, здесь, возможно, GridLayout, и вызывать revalidate() и repaint() в контейнере jpFullofButtons JPanel после добавления в него компонентов.

Дополнительное примечание о вашей попытке MRE: там почти, но вы все еще оставили требование DAO, а также неопределенный класс, DataVO, что не позволяет нам копировать, вставлять и запускать ваш код.

Мой пример MRE:

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

Другие вопросы по теме