自从我上次进行Swing编程以来已经有一段时间了,今天我又回到了它。我有一个简单的JList
,由DefaultListModel
支持。我还有JButton
,会显示JFileChooser
。选择目录时,JList
应填充所选目录下的文件名。
我发现偶尔(实际上它经常随机发生),列表不会更新,直到我点击(看似空白)列表。我想通过使用DefaultListModel
,我可以调用addElement()
来触发fireIntervalAdded(它应该重新绘制列表,容器等)?另外,我相信在EDT中调用actionPerformed()
方法,所以我应该能够更新DefaultListMode
l。无论如何......我也尝试在列表,容器等上调用revalidate()
和repaint()
,但也没有任何成功。
其次,当列表中已经有一些项目时,单击按钮(触发文件选择器显示)将清除JList
条目(不在模型上调用clear()
)。
源代码位于:
https://github.com/alexwibowo/spider
这是代码的摘要(希望它已经足够了)
package org.github.alexwibowo.spider.gui;
import com.jgoodies.forms.factories.CC;
import com.jgoodies.forms.layout.FormLayout;
import javax.swing.*;
public class MainPanel extends JPanel {
public MainPanel() {
initComponents();
}
private void initComponents() {
toolBar1 = new JToolBar();
openFolderButton = new JButton();
splitPane1 = new JSplitPane();
scrollPane1 = new JScrollPane();
fileList = new JList();
//======== this ========
setLayout(new FormLayout(
"default:grow",
"default, $lgap, fill:default:grow"));
//======== toolBar1 ========
{
toolBar1.setFloatable(false);
//---- openFolderButton ----
openFolderButton.setIcon(UIManager.getIcon("Tree.openIcon"));
openFolderButton.setBorder(new EmptyBorder(5, 5, 5, 5));
toolBar1.add(openFolderButton);
}
add(toolBar1, CC.xy(1, 1));
//======== splitPane1 ========
{
//======== scrollPane1 ========
{
//---- fileList ----
fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
scrollPane1.setViewportView(fileList);
}
splitPane1.setLeftComponent(scrollPane1);
}
add(splitPane1, CC.xy(1, 3));
}
protected JToolBar toolBar1;
protected JButton openFolderButton;
protected JSplitPane splitPane1;
protected JScrollPane scrollPane1;
protected JList fileList;
}
以及扩展上述内容的面板。这是处理向列表添加文件名的类:
package org.github.alexwibowo.spider.gui
import javax.swing.*
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
class BarcodeMainPanel extends MainPanel {
private DefaultListModel<String> listModel = new DefaultListModel<String>()
BarcodeMainPanel() {
initModels()
initEventHandling()
}
protected void initModels() {
fileList.model = listModel
}
protected void initEventHandling() {
openFolderButton.addActionListener(new ActionListener() {
@Override
void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setLocation(50, 50);
if (chooser.showOpenDialog(BarcodeSpiderMainFrame.instance()) == JFileChooser.APPROVE_OPTION) {
listModel.clear()
File selectedDirectory = chooser.getSelectedFile()
selectedDirectory.eachFile {
listModel.addElement(it.name)
}
} else {
System.out.println("No Selection ");
}
}
})
}
}
包含面板的框架(仅为完整性):
package org.github.alexwibowo.spider.gui
import groovy.transform.Synchronized
import javax.swing.*
import java.awt.*
class BarcodeSpiderMainFrame extends JFrame{
private static BarcodeSpiderMainFrame INSTANCE;
BarcodeSpiderMainFrame(String title) throws HeadlessException {
super(title)
}
@Synchronized
public static BarcodeSpiderMainFrame instance() {
if (INSTANCE == null) {
INSTANCE = new BarcodeSpiderMainFrame("Spider")
INSTANCE.minimumSize = new Dimension(800,600)
INSTANCE.maximumSize = new Dimension(1024,768)
INSTANCE.defaultCloseOperation = EXIT_ON_CLOSE
}
INSTANCE.initializeContent()
INSTANCE.visible = true
INSTANCE
}
private void initializeContent() {
BarcodeMainPanel mainPanel = new BarcodeMainPanel()
this.contentPane.add(mainPanel);
}
}
最后是发射器(仅为完整性):
package org.github.alexwibowo.spider
import org.github.alexwibowo.spider.gui.BarcodeSpiderMainFrame
import javax.swing.*
@Singleton
class SpiderLauncher {
BarcodeSpiderMainFrame barcodeSpiderMainFrame
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SpiderLauncher.instance.run(args);
}
});
}
void run(String[] args) {
barcodeSpiderMainFrame = BarcodeSpiderMainFrame.instance()
barcodeSpiderMainFrame.show()
}
}
答案 0 :(得分:1)
这就是修复它的原因。 在BarcodeSpiderMainFrame中,删除对setVisible的调用。所以它看起来像:
public static BarcodeSpiderMainFrame instance() {
if (INSTANCE == null) {
INSTANCE = new BarcodeSpiderMainFrame("Spider")
INSTANCE.minimumSize = new Dimension(800,600)
INSTANCE.preferredSize = new Dimension(1024,768)
INSTANCE.maximumSize = new Dimension(1024,768)
INSTANCE.defaultCloseOperation = EXIT_ON_CLOSE
}
INSTANCE.initializeContent()
// INSTANCE.visible = true // remove this line
INSTANCE
}
并在启动器中调用setVisible()
@Singleton
class SpiderLauncher {
BarcodeSpiderMainFrame barcodeSpiderMainFrame
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SpiderLauncher.instance.run(args);
}
});
}
void run(String[] args) {
barcodeSpiderMainFrame = BarcodeSpiderMainFrame.instance()
barcodeSpiderMainFrame.pack()
barcodeSpiderMainFrame.setVisible(true) // add this line
}
}
我添加了对pack()的调用。但我不认为这真的很重要。以上是如何解决我的问题的?我不知道。如果有人能够解释实际发生的事情,那就太好了。