我目前正在尝试从另一个类改变JList
的元素。我喜欢将GUI与工作应用程序分开。
在这个例子中,我有一个只有JScrollPane
和JButton
的GUI。我有一个应用程序。这是一个可运行的类,如果按下按钮,它应该将runnable设置为true,并且应该添加一些元素。但是我无法解决如何以GUI刷新并立即显示元素的方式链接这两个类。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestGUI {
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private JScrollPane scrollPane = new JScrollPane(panel);
private TestApi testApi;
private JButton button = new JButton();
private DefaultListModel<Person> personDefaultListModel = new DefaultListModel<Person>();
private JList<Person> personJList = new JList<>(personDefaultListModel);
public TestGUI () {
frame.setSize(600,400);
frame.setTitle("TestGUI");
frame.setLayout(new BorderLayout());
addPerson(new Person("Fresh","Prince"));
panel.add(personJList);
scrollPane.createVerticalScrollBar();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
startAdding();
}
});
button.setText("press me");
frame.add(scrollPane,BorderLayout.CENTER);
frame.add(button,BorderLayout.SOUTH);
frame.setVisible(true);
testApi = new TestApi(panel);
}
private void addPerson (Person p){
personDefaultListModel.addElement(p);
}
private void startAdding(){
this.testApi.setRunning(true);
}
public static void main (String... args){
new TestGUI();
}
}
import javax.swing.*;
public class TestApi implements Runnable{
private boolean running = false;
private DefaultListModel<Person> personDefaultListModel = new DefaultListModel<>();
private JList<Person> personJList = new JList<>(personDefaultListModel);
private JPanel panel = new JPanel();
public TestApi (JPanel panel){
this.panel = panel;
}
public void setRunning(boolean running) {
this.running = running;
}
public void run(){
while (running){
addElements();
panel.removeAll();
panel.add(personJList);
setRunning(false);
}
}
private void addElements(){
addPerson(new Person("Margot","Hinterseer"));
addPerson(new Person("bla", "blubb"));
}
private void addPerson (Person p){
personDefaultListModel.addElement(p);
}
}
public class Person {
private final String name;
private final String surname;
public Person(String name, String surname) {
this.name = name;
this.surname = surname;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
@Override
public String toString() {
return name + " " + surname;
}
}
如果你能在那里帮助我会好的。
根据注释,允许外部类改变类的一种方法是为类提供外部类可以调用的公共方法,然后将该类的键实例的实例传递到需要它的位置。例如,考虑改变
private void addPerson (Person p){
personDefaultListModel.addElement(p);
}
公开。
public void addPerson (Person p){
personDefaultListModel.addElement(p);
}
如果您需要更改列表的完整模型,请为此类提供一个允许您执行此操作的公共方法:
public void setListModel (DefaultListModel<Person> model){
personJList.setModel(model);
}
您的代码的其他问题:
while (true)
循环将冻结您的应用程序,因此在这里没有位置。例如,假设你想启动一个允许另一个类将Person添加到主GUI JList的对话框窗口,你可以这样做:
import java.awt.BorderLayout;
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class MainPersonGui extends JPanel {
private DefaultListModel<Person> personDefaultListModel = new DefaultListModel<>();
private JList<Person> personJList = new JList<>(personDefaultListModel);
private JDialog addPersonDialog;
public MainPersonGui() {
personJList.setVisibleRowCount(15);
personJList.setPrototypeCellValue(
new Person("xxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxx"));
addPerson(new Person("Duck", "Donald"));
JButton addPersonBtn = new JButton(new AbstractAction("Add Person") {
@Override
public void actionPerformed(ActionEvent e) {
if (addPersonDialog == null) {
Window owner = SwingUtilities.getWindowAncestor(MainPersonGui.this);
addPersonDialog = new JDialog(owner, "Add Person", ModalityType.MODELESS);
addPersonDialog.add(new AddPersonPanel(MainPersonGui.this));
addPersonDialog.pack();
}
addPersonDialog.setVisible(true);
}
});
setLayout(new BorderLayout());
add(new JScrollPane(personJList));
add(addPersonBtn, BorderLayout.PAGE_END);
}
// !! make this public
public void addPerson(Person p) {
personDefaultListModel.addElement(p);
}
private static void createAndShowGui() {
MainPersonGui mainPanel = new MainPersonGui();
JFrame frame = new JFrame("Test GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class AddPersonPanel extends JPanel {
private MainPersonGui personGui;
private JTextField firstNameField = new JTextField(10);
private JTextField lastNameField = new JTextField(10);
public AddPersonPanel(MainPersonGui personGui) {
this.personGui = personGui; // set the reference to main
add(new JLabel("First Name:"));
add(firstNameField);
add(Box.createHorizontalStrut(20));
add(new JLabel("Last Name:"));
add(lastNameField);
add(Box.createHorizontalStrut(20));
add(new JButton(new AbstractAction("Insert Name") {
@Override
public void actionPerformed(ActionEvent e) {
String name = firstNameField.getText();
String surname = lastNameField.getText();
Person person = new Person(name, surname);
// **** here call the main's addPerson() method ****
personGui.addPerson(person);
firstNameField.setText("");
lastNameField.setText("");
}
}));
}
}