只要发生更新,JList 位置就会重置为默认值

JList position resets to default whenever update occurs

list 是接受来自 Action1 的输入,但是,每当将新元素添加到列表时,列表的位置都会移回默认的 top-middle 位置。

调整框架大小时也会发生这种情况,因此我临时修复了 frame.setResizable(false) 行,但我不希望它成为永久性的。

我该如何解决这两个问题?

import static java.lang.String.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionListener;

public class lists 
{

static String newUrl;
static DefaultListModel<String> model = new DefaultListModel<String>();
static int listXCoord = 650;
static int listYCoord = 10;

public static void createGUI()
{

    JFrame frame = new JFrame();
    frame.setVisible(true);
    frame.setSize(800,600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);

    JPanel panel = new JPanel();
    frame.add(panel);

    JButton addurl = new JButton("Add URL");
    panel.add(addurl);
    addurl.addActionListener(new Action1());
    JButton remurl = new JButton("Remove URL");
    panel.add(remurl);


    //model.addElement("one");
    //model.addElement("two");
    //model.addElement("three");

    JList list = new JList<String>(model);
    list.setCellRenderer(new DefaultListCellRenderer());
    list.setVisible(true);
    list.setLocation(listXCoord, listYCoord);
    list.setBackground(new Color(186, 203, 250));
    //list.setLocation(650, 10);


    panel.add(list);
    list.setSize(130, 540);
}
static class Action1 implements ActionListener
{        
    public void actionPerformed (ActionEvent e) 
    {

        newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
        model.addElement(newUrl);
    }
}   
public static void main(String[] args) 
{

    createGUI();

} 
}

基本上,您是在与布局管理器 (Flowlayout) 战斗并输了。当您向 JList 添加新元素时,容器层次结构将重新生效,这会导致布局管理器重新布局其容器的内容

基本的解决方案是使用不同的布局,但是,JFrame 使用 BorderLayout,所以不是将 JList 添加到 JPanel,你可以简单地将它添加到框架的 EAST 位置而不是

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListCellRenderer;
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.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Lists {

    static String newUrl;
    static DefaultListModel<String> model = new DefaultListModel<String>();
    static int listXCoord = 650;
    static int listYCoord = 10;

    public static void createGUI() {

        JFrame frame = new JFrame();
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        frame.add(panel);

        JButton addurl = new JButton("Add URL");
        panel.add(addurl);
        addurl.addActionListener(new Action1());
        JButton remurl = new JButton("Remove URL");
        panel.add(remurl);

        //model.addElement("one");
        //model.addElement("two");
        //model.addElement("three");
        JList list = new JList<String>(model);
        list.setCellRenderer(new DefaultListCellRenderer());
        list.setVisible(true);
        list.setLocation(listXCoord, listYCoord);
        list.setBackground(new Color(186, 203, 250));
        //list.setLocation(650, 10);

        frame.add(new JScrollPane(list), BorderLayout.EAST);

        frame.setVisible(true);
    }

    static class Action1 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
            model.addElement(newUrl);
        }
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                createGUI();
            }
        });

    }
}

有关详细信息,请参阅 Laying Out Components Within a Container, How to Use BorderLayout and How to use FlowLayout

您还应该最后调用 setVisible,在所有组件都添加到框架之后,这样可以减少某些组件在您认为应该显示的时候不显示的可能性。

JList 也将受益于包含在 JScrollPane 中。有关详细信息,请参阅 How to Use Lists and How to Use Scroll Panes