Добавленная JPanel отображается только при добавлении из другого метода? - PullRequest
0 голосов
/ 28 апреля 2019

enter image description here Я пытаюсь создать программу, которая сначала добавляет строки JPanel. После добавления JPanel вы можете добавить квадраты, нажав «Добавить по горизонтали» и указав индекс строки (от 0), к которому следует добавить квадрат.

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

Вы можете увидеть демонстрацию этого на прикрепленном изображении, где первые квадраты индекса 2 и индекса 3 просто невидимы без добавления JLabel.

Как я могу изменить свой код, чтобы первый квадрат отображался сразу после нажатия «Добавить вертикаль» JButton?

import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import java.awt.event.*;
public class HistoryEditor extends JFrame{


public static Color randomColor(){
    return new Color((float)Math.random(), (float)Math.random(), (float)Math.random());
}

public HistoryEditor(){

    setLayout(new BorderLayout());

    final JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
    JPanel controlPanel = new JPanel(new FlowLayout());
    final JTextField tf = new JTextField(20);
    JButton addVertical = new JButton("Add Vertical");
    JButton addHorizontal = new JButton("Add Horizontal");
    JButton removeVertical = new JButton("Remove Vertical");

    addVertical.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            JPanel newPanel = new JPanel();
            newPanel.setPreferredSize( new Dimension(getWidth(), 50) );
            newPanel.setMaximumSize( newPanel.getPreferredSize() );
            newPanel.setMinimumSize( newPanel.getPreferredSize() );
            newPanel.setBackground( HistoryEditor.randomColor() );
            newPanel.setLayout( new BoxLayout( newPanel, BoxLayout.X_AXIS ) );

            JPanel eventPanel = new JPanel();
            eventPanel.setBackground( HistoryEditor.randomColor() );
            eventPanel.setMaximumSize( new Dimension(50, newPanel.getHeight() ) );
            eventPanel.setMinimumSize( new Dimension(50, newPanel.getHeight() ) );
            eventPanel.setPreferredSize( new Dimension(50, newPanel.getHeight() ) );
            eventPanel.add( new JLabel( tf.getText() ) );
            eventPanel.revalidate();
            newPanel.add(eventPanel);
            newPanel.revalidate();
            mainPanel.add( newPanel );
            mainPanel.revalidate();
            mainPanel.repaint();
            eventPanel.repaint();   


        }
    });

    addHorizontal.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            try{
                int index = Integer.parseInt(tf.getText());
                JPanel selectedPanel = (JPanel)mainPanel.getComponent( index );

                JPanel eventPanel = new JPanel();
                eventPanel.setBackground( HistoryEditor.randomColor() );
                eventPanel.setMaximumSize(new Dimension(50, selectedPanel.getHeight()));
                eventPanel.setMinimumSize(new Dimension(50, selectedPanel.getHeight()));
                eventPanel.add( new JLabel( tf.getText() ) );
                selectedPanel.add(eventPanel);
                selectedPanel.revalidate();
                selectedPanel.repaint();

            }catch(Exception ex){}
        }
    });


    removeVertical.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            try{
                int index = Integer.parseInt(tf.getText());
                mainPanel.remove(index);
                mainPanel.revalidate();
                mainPanel.repaint();

            }catch(Exception ex){}
        }
    });


    controlPanel.add(tf);
    controlPanel.add(addVertical);
    controlPanel.add(addHorizontal);
    controlPanel.add(removeVertical);   
    add(mainPanel, BorderLayout.CENTER);
    add(controlPanel, BorderLayout.SOUTH);
    setSize(1000, 1000);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[]args){
    HistoryEditor he = new HistoryEditor();
}

}

1 Ответ

1 голос
/ 28 апреля 2019
eventPanel.setPreferredSize( new Dimension(50, newPanel.getHeight() ) );

Компоненты имеют размер (0, 0) при создании.

Таким образом, вы устанавливаете предпочтительный размер вашей EventPanel равным (50, 0), что означает, что добавленный компонент не будет виден, потому что высота панели равна 0.

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

Кроме того, нет необходимости в EventPanel. Вы можете просто добавить ярлык прямо на новую панель. Вам просто нужно убедиться, что вы используете:

label.setOpaque(true);

так что фон этикетки будет окрашен.

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

...