Заставить два JList иметь одинаковый размер в Java Swing? - PullRequest
1 голос
/ 25 мая 2020

Я пытаюсь создать компонент JavaSwing, который меняет местами элементы между двумя JList. Работает нормально. Но когда какой-то элемент из одного списка становится длиннее, он меняет размеры, чтобы соответствовать тексту. Я не хочу, чтобы это случилось. Я добавил JScrollBar в каждый список JLists, и если я изменю размер окна, они появятся. Но я хочу, чтобы размер списков оставался неизменным.

Вот скриншот моего проекта. Я не мог не заметить, что вертикальный размер Jpanel влияет на то, как отрисовываются JLists. См. 3-й снимок экрана, панель меньше и работает нормально.

Вот код, чтобы вы могли его протестировать. Попробуйте переместить каждую длинную запись в одну таблицу и посмотрите, что произойдет.

package table.resize.problem;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * @author theasdas
 */
public class TableResizeProblem {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MainFrame window = new MainFrame();
            }
        });
    }
}

class MainFrame extends JFrame {

    //components:
    private JList list1 = new JList();
    private JList list2 = new JList();
    private DefaultListModel model1 = new DefaultListModel();
    private DefaultListModel model2 = new DefaultListModel();
    private JButton btnMove = new JButton("Move");
    //variables:
    private int selectedList = 0; //defines which list is focused by the user

    /**
     * Constructor.
     */
    public MainFrame() {
        //initial configuration
        configureSelf();
        configureComponents();
        setListeners();
        placeComponents();
        this.setVisible(true);
    }

    /**
     * Configure this component.
     */
    private void configureSelf() {
        this.setLayout(new GridBagLayout());
        this.setSize(600, 800);
    }

    /**
     * Configure other components.
     */
    private void configureComponents() {
        //lists
        list1.setModel(model1);
        list2.setModel(model2);
        //models
        for (int i = 0; i < 4; i++) {
            model1.addElement("item " + (i + 1));
            model1.addElement("looooong item" + (i + 1));
        }
        for (int i = 0; i < 4; i++) {
            model2.addElement("item " + (i + 1));
            model2.addElement("looooong item" + (i + 1));
        }
        //button
        btnMove.setEnabled(false);
    }

    private void setListeners() {

        //list focus listener
        FocusListener onFocus = new FocusListener() {
            @Override
            public void focusGained(FocusEvent fe) {
                checkFocus((JList) fe.getSource());
            }

            @Override
            public void focusLost(FocusEvent fe) {
                //do nothing
            }
        };
        //add listener to lists
        this.list1.addFocusListener(onFocus);
        this.list2.addFocusListener(onFocus);

        //button action listener
        ActionListener onClick = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                swapItem();
            }
        };
        this.btnMove.addActionListener(onClick);
    }

    /**
     * Checks which list is focused.
     *
     * @param list
     */
    private void checkFocus(JList list) {

        if (list == list1) {
            list2.clearSelection();
            selectedList = 1;
            btnMove.setEnabled(true);
        } else {
            list1.clearSelection();
            selectedList = 2;
            btnMove.setEnabled(true);
        }
    }

    /**
     * Swap an item between lists.
     */
    private void swapItem() {

        if (selectedList == 0 && (list1.getSelectedValue() == null || list2.getSelectedValue() == null)) {
            JOptionPane.showMessageDialog(new JPanel(), "Bruh...", "Bruh moment has been achieved.", JOptionPane.ERROR_MESSAGE);
            return;
        } else {
            if (selectedList == 1) {
                model2.addElement(list1.getSelectedValue());
                model1.removeElement(list1.getSelectedValue());
            } else {
                model1.addElement(list2.getSelectedValue());
                model2.removeElement(list2.getSelectedValue());
            }
        }
        selectedList = 0;
    }

    /**
     * Places components in a grid.
     */
    private void placeComponents() {
        GridBagConstraints g = new GridBagConstraints();

        //(0, 0) list1
        g.gridx = 0;
        g.gridy = 0;
        g.weightx = 1;
        g.weighty = 1;
        g.anchor = GridBagConstraints.PAGE_START;
        g.fill = GridBagConstraints.BOTH;
        g.insets = new Insets(5, 5, 5, 5);
        this.add(list1, g);
        //(1, 0) list 2
        g.gridx = 1;
        this.add(list2, g);
        //(0, 1) button
        g.gridx = 0;
        g.gridy = 1;
        g.fill = GridBagConstraints.HORIZONTAL;
        g.weighty = 0;
        g.gridwidth = GridBagConstraints.REMAINDER;
        this.add(btnMove, g);
    }

}

Итак, чего мне не хватает?

1 Ответ

0 голосов
/ 26 мая 2020

Попробуйте следующее. Я внес некоторые изменения.

  • Расширять JFrame - не лучшая идея. Поэтому я расширил JPanel и добавил его во фрейм.
  • Я сделал каждый JList достаточно большим, чтобы он располагался рядом, а также для места внизу для кнопки.
  • И ваш JList и Модель являются общими типами c, поэтому я их тоже добавил. Здесь используется BorderLayout, который, кажется, работает нормально.
  • Я также переопределил getInsets для JLists и добавил границу, чтобы их очертить.

Я также добавил несколько комментариев в код . Пожалуйста, дайте мне знать, если это не сработает.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

/**
 * @author theasdas
 */
public class TableResizeProblem {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MainFrame window = new MainFrame();
            }
        });
    }
}

class MainFrame extends JPanel {

    //components:
    JFrame frame = new JFrame();

    private JList<String> list1 = new JList<>() {
        public Insets getInsets() {
            return new Insets(5,5,5,5);
        }
    };
    private JList<String> list2 = new JList<>() {
        public Insets getInsets() {
            return new Insets(5,5,5,5);
        }
    };

    private DefaultListModel<String> model1 = new DefaultListModel<>();
    private DefaultListModel<String> model2 = new DefaultListModel<>();
    private JButton btnMove = new JButton("Move");
    //variables:
    private int selectedList = 0; //defines which list is focused by the user

    /**
     * Constructor.
     */
    public MainFrame() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(this);
        setLayout(new BorderLayout());
        list1.setPreferredSize(new Dimension(300,600));
        list2.setPreferredSize(new Dimension(300,600));


        list1.setBorder(new LineBorder(Color.black));
        list2.setBorder(new LineBorder(Color.black));
        add(list1,BorderLayout.WEST);
        add(list2,BorderLayout.EAST);
        add(btnMove,BorderLayout.SOUTH);
        configureComponents();
        setListeners();
        // pack the frame and invoke the layouts
        frame.pack();
        // center the frame on the screen.
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }


    /**
     * Configure other components.
     */
    private void configureComponents() {
        //lists
        list1.setModel(model1);
        list2.setModel(model2);
        //models
        for (int i = 0; i < 4; i++) {
            model1.addElement("item " + (i + 1));
            model1.addElement("looooong item" + (i + 1));
        }
        for (int i = 0; i < 4; i++) {
            model2.addElement("item " + (i + 1));
            model2.addElement("looooong item" + (i + 1));
        }
        //button
        btnMove.setEnabled(false);
    }

    private void setListeners() {

        //list focus listener
        FocusListener onFocus = new FocusListener() {
            @Override
            public void focusGained(FocusEvent fe) {
                checkFocus((JList<String>) fe.getSource());
            }

            @Override
            public void focusLost(FocusEvent fe) {
                //do nothing
            }
        };
        //add listener to lists
        this.list1.addFocusListener(onFocus);
        this.list2.addFocusListener(onFocus);

        //button action listener
        ActionListener onClick = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                swapItem();
            }
        };
        this.btnMove.addActionListener(onClick);
    }

    /**
     * Checks which list is focused.
     *
     * @param list
     */
    private void checkFocus(JList list) {

        if (list == list1) {
            list2.clearSelection();
            selectedList = 1;
            btnMove.setEnabled(true);
        } else {
            list1.clearSelection();
            selectedList = 2;
            btnMove.setEnabled(true);
        }
    }

    /**
     * Swap an item between lists.
     */
    private void swapItem() {

        if (selectedList == 0 && (list1.getSelectedValue() == null || list2.getSelectedValue() == null)) {
            JOptionPane.showMessageDialog(new JPanel(), "Bruh...", "Bruh moment has been achieved.", JOptionPane.ERROR_MESSAGE);
            return;
        } else {
            if (selectedList == 1) {
                model2.addElement(list1.getSelectedValue());
                model1.removeElement(list1.getSelectedValue());
            } else {
                model1.addElement(list2.getSelectedValue());
                model2.removeElement(list2.getSelectedValue());
            }
        }
        selectedList = 0;
    }
}

...