【问题标题】:Displaying multiple JList to JFrame将多个 JList 显示到 JFrame
【发布时间】:2017-08-09 14:04:50
【问题描述】:

我试图将许多 JList 放在仅显示 2 个名称的不同滚动窗格中。我将 mt 列表存储在向量向量中,此结构表示一周中的几天,每天都有多个“班次”。

import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.*;

public class AutoScheduel extends JFrame{
private JList leftlist;
private JList leftlist1;
private JList tempList;
private int frameX = 50;
private int frameY = 50;
//private JList rightlist;
//private JButton movebutton;
static Employee Amanda = new Employee("Amanda",0,false); static Employee      Austin = new Employee("Austin",0,false); static Employee Conner = new Employee("Conner",0,false);
static Employee Faith = new Employee("Faith",0,false); static Employee Jospeh = new Employee("Jospeh",0,false); static Employee Lexi = new Employee("Lexi",0,false);
static Employee Matthew = new Employee("Matthew",0,false); static Employee     Samie = new Employee("Samie",0,false); static Employee Tanner = new     Employee("Tanner",0,false);
static Employee Valerie = new Employee("Valeire",0,false); static Employee     Will = new Employee("Will",0,false); static Employee Zack = new     Employee("Zack",0,false);
private static String[] employeesNames= {Amanda.getName(),Austin.getName(),Conner.getName(),Faith.getName(),Jospeh.getName(),
        Lexi.getName(),Matthew.getName(),Samie.getName(),Tanner.getName(),Valerie.getName(),Will.getName(),Zack.getName()};
private Vector<JList> weekday;
private Vector<JList> weekend;
private Vector<Vector<JList>> v;
public AutoScheduel(){
    super("Cambridge AutoSchedueler");
    setLayout(new FlowLayout());
    pack();
    setLocationRelativeTo(null);
    leftlist = new JList(employeesNames);
    leftlist.setVisibleRowCount(2);
    leftlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    //add(new JScrollPane(leftlist));

    leftlist1 = new JList(employeesNames);
    leftlist1.setVisibleRowCount(2);
    leftlist1.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    //add(new JScrollPane(leftlist));

    v = new Vector<Vector<JList>>();
    weekday = new Vector<JList>();
    weekend = new Vector<JList>();
    for(int i=0;i<6;i++){
        weekday.addElement(leftlist);
    }
    for(int i=0;i<5;i++){
        weekend.add(leftlist1);
    }
    for(int i=0;i<5;i++){
        v.add(weekday);
    }
    v.add(weekend);
    v.add(weekend);

    tempList = new JList();
    leftlist.setPreferredSize(new Dimension(50,20));
    //leftlist.setLocation(50, 50);
    //add(new JScrollPane(leftlist));
    //add(new JScrollPane(v.get(1).get(3)));


    for(int i = 0; i<v.size();i++){
        for(int j = 0 ; i<v.get(i).size();i++){
            tempList = v.get(i).get(j);
            frameY += 40;
            tempList.setLocation(frameX,frameY);
            add(new JScrollPane(tempList));
        }
        frameX += 50;
    }




}
public static void main(String[] args){
   AutoScheduel go = new  AutoScheduel();
   go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   go.setSize(600, 600);

   go.setVisible(true);

}

}

目前,我得到一个列表,其中显示了我想要的正确列表,但该列表前面只有点表示有许多列表相互堆叠。我认为这是因为我正在使用流布局。当我尝试使用不同的列表,然后将其添加到 Jframe 中时,它可以工作,但由于我需要 34 个列表,我只想使用 for 循环将它们放入我的向量中。如果有人可以帮助 JFrame 中的格式化,那将是很棒的,我需要将它保存在一个数据结构中,在那里我仍然可以访问元素并设置为看起来像一个带有可选列表的一周。提前致谢

【问题讨论】:

  • 为什么要将相同的对象重复添加到向量中,以便向量包含对单个对象的多个引用?
  • 你的目标是什么显示结果?
  • 您的代码非常复杂,看起来包含许多不必要的复杂性,至少让我很难理解,而且我认为对于 也是如此,因为它没有做什么你认为它正在做。考虑简化和重构。
  • 例如,您有这些Vector&lt;Vectors&lt;JList&gt;&gt;,但尽管您创建了所有集合,但它们拥有 3 个且只有 3 个 JLists 实例,并且没有更多,尽管您认为您有 "put many JList in different scroll panes"

标签: java swing jframe jlist


【解决方案1】:

您需要为您希望显示的每个 JList 创建一个新 JList 和一个新模型。您当前的代码只创建了 3 个 JList,并尝试在 GUI 中重复放置它们,但这不起作用。

例如,假设您想在一周的 5 个工作日显示 5 个 JList,其中一个显示员工姓名,您可以创建一个 JList 集合并在 for 循环中创建 5 个 JList,每个都有模型。此外,不要从 Employee 对象中提取姓名,而是用实际的 Employee 对象填充 JList 并使用渲染器告诉 JList 仅显示员工姓名。例如:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.util.HashMap;
import java.util.Map;

import javax.swing.*;

@SuppressWarnings("serial")
public class Scheduler2 extends JPanel {
    private static final Employee2[] employees = { 
            new Employee2("Amanda", 0, false), 
            new Employee2("Austin", 0, false),
            new Employee2("Conner", 0, false), 
            new Employee2("Faith", 0, false), 
            new Employee2("Jospeh", 0, false),
            new Employee2("Lexi", 0, false), 
            new Employee2("Matthew", 0, false), 
            new Employee2("Samie", 0, false),
            new Employee2("Tanner", 0, false), 
            new Employee2("Valeire", 0, false), 
            new Employee2("Will", 0, false),
            new Employee2("Zack", 0, false) };
    private static final String[] WEEK_DAYS = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };

    // associates each list with the day of the week
    private Map<String, JList<Employee2>> weekDayListMap = new HashMap<>();

    public Scheduler2() {
        // layout to hold 1 row, multiple columns
        setLayout(new GridLayout(1, 0));
        // renderer that shows employee names only
        EmployeeCellRenderer cellRenderer = new EmployeeCellRenderer();
        for (int i = 0; i < WEEK_DAYS.length; i++) {
            // new model for each week
            DefaultListModel<Employee2> listModel = new DefaultListModel<>();
            for (Employee2 employee : employees) {
                // fill the model
                listModel.addElement(employee);
            }
            // new list for each day of the week with model
            JList<Employee2> list = new JList<>(listModel);
            list.setVisibleRowCount(4);
            list.setCellRenderer(cellRenderer); // so shows name only
            String prototypeName = "aaaaaaaaaaaaaaaaaaa";
            list.setPrototypeCellValue(new Employee2(prototypeName, 0, false));
            weekDayListMap.put(WEEK_DAYS[i], list); // put in collection (if needed)
            JScrollPane scrollPane = new JScrollPane(list);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

            // if we want a border around the jscrollpane showing the day of the week
            JPanel container = new JPanel(new BorderLayout());
            container.add(scrollPane);
            container.setBorder(BorderFactory.createTitledBorder(WEEK_DAYS[i]));
            add(container);
        }
    }

    // JList renderer to display only names
    private class EmployeeCellRenderer extends DefaultListCellRenderer {
        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
                boolean cellHasFocus) {
            if (value == null) {
                value = "";
            } else {
                Employee2 empl = (Employee2) value;
                value = empl.getName();
            }
            return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Scheduler2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new Scheduler2());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

// you never gave us the employee class, so I had to create one of my own
class Employee2 {
    private String name;
    private int value;
    private boolean bool;

    public Employee2(String name, int value, boolean bool) {
        this.name = name;
        this.value = value;
        this.bool = bool;
    }

    public String getName() {
        return name;
    }

    public int getValue() {
        return value;
    }

    public boolean isBool() {
        return bool;
    }
}

关于,

你能解释一下你实际上是在哪里将列表添加到框架中的吗?

我将 JList 添加到 JScrollPane。然后我可以将 JScrollPane 添加到主 JPanel,即 this,但由于我想在 JScrollPane 周围加上一周中的某一天的边框,所以我创建了另一个 JPanel,称为容器,给它一个 BorderLayout,将 JScrollPane 添加到它,BorderLayout.CENTER(默认情况下),然后给这个外部“包装器”JPanel 一个带有星期字符串的标题边框。然后我将它添加到主 JPanel。都在这里:

// create JList w/ model
JList<Employee2> list = new JList<>(listModel);

// .....

// add JList to JScrollpane
JScrollPane scrollPane = new JScrollPane(list);


// .....

// create "wrapper" JPanel 
JPanel container = new JPanel(new BorderLayout());
container.add(scrollPane);  // and place JScrollPane into it
container.setBorder(BorderFactory.createTitledBorder(WEEK_DAYS[i]));

// add wrapper JPanel to the GUI
add(container);

【讨论】:

  • 非常感谢您的帮助,只显示对象名称的单元格渲染器很聪明。我尝试做类似的事情但没有用,这就是我提取每个名称以显示的原因。您几乎完全按照我的需要进行了格式化,我只需要将相同的列表放在一周中的几天下的列中,以用于当天的不同班次。我现在将尝试通过修改您的代码来自己做到这一点,因为它比我尝试的要好得多。
  • 你能解释一下你实际上是在哪里将列表添加到框架中的吗?
  • 我看到 for 循环将员工添加到列表中,然后您修改了要呈现的列表以及要显示的名称,但我不太确定“weekDayListMap.put(WEEK_DAYS[i],列表);“确实如此。感谢您的宝贵时间!
  • @ZackChristie:见编辑回答。至于地图,只有当您需要将每个工作日的 JList 与其星期几字符串相关联时。在理解这一点之前,您需要查找并了解 HashMap 等 Map 的作用。
  • 我对它们有点熟悉,只是在java中从未见过它的语法,但感谢您的描述。因此,如果我需要在一天下添加更多列表(列表的轮班),我需要在工作日添加 6 个,在周末需要 5 个,我只需要在员工列表中创建更多 JScrollPanes 并添加他们在吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 2014-08-06
  • 2017-04-09
  • 2013-04-04
相关资源
最近更新 更多