我使用基于Swing的简单GUI在Java中编写了一个小注释器,但我遇到的问题让我感到非常震惊。 问题是:我有一个jlist和两个jbuttons修改这样的jlist,这两个按钮有SAME监听器,但它们的工作方式不同。 所有它应该像这样工作:一旦你在jlist中选择一行你可以将其标记为ON TOPIC或OFF TOPIC(使用两个按钮),行会改变颜色然后选择下一行但是;即使选择在右侧(下一个),它突出显示下一个仅为OFF主题按钮,为什么?
以下是代码:
public class TweetsAnnotator {
static Boolean[] annotations = null;
@SuppressWarnings("rawtypes")
static JList jl;
static JButton offbutton = new JButton("OFF Topic");
static JButton onbutton = new JButton("ON Topic");
static String file = "inception_TweetList";
public TweetsAnnotator() {
}
/**
* @param args
* @throws IOException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
// Read Tweets from file
ObjectInputStream load = new ObjectInputStream(new FileInputStream(file));
ArrayList<String> list = (ArrayList<String>) load.readObject();
load.close();
System.out.println(list.size() + " Tweets read from: " + file);
// Check and read annotations
File fileannot = new File(file + "Annotations");
if (fileannot.exists()) {
System.out.println("esiste, leggo");
ObjectInputStream loadannot = new ObjectInputStream(new FileInputStream(file + "Annotations"));
annotations = (Boolean[]) loadannot.readObject();
loadannot.close();
} else {
System.out.println("non esiste, creo poi leggo");
ObjectOutputStream save = new ObjectOutputStream(new FileOutputStream(file + "Annotations"));
Boolean[] creatannotations = new Boolean[list.size()];
for (int i=0; i<list.size(); i++) {
creatannotations[i] = (Boolean) null;
}
save.writeObject(creatannotations);
save.close();
ObjectInputStream loadannot = new ObjectInputStream(new FileInputStream(file + "Annotations"));
annotations = (Boolean[]) loadannot.readObject();
loadannot.close();
}
System.out.println(annotations.length + " Annotations loaded");
// Buttons
offbutton.setActionCommand("off");
offbutton.addActionListener(new ButtonListener());
offbutton.setEnabled(false);
onbutton.setActionCommand("on");
onbutton.addActionListener(new ButtonListener());
onbutton.setEnabled(false);
// ButtonPanel
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
buttonPane.add(onbutton);
buttonPane.add(offbutton);
// JList
jl = new JList((Object[])list.toArray());
jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jl.setLayoutOrientation(JList.VERTICAL);
jl.setVisibleRowCount(-1);
jl.setCellRenderer(new MyCellRenderer());
ListSelectionListener listSelectionListener = new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (jl.getSelectedIndex() == -1) {
//No selection, disable buttons.
onbutton.setEnabled(false);
offbutton.setEnabled(false);
} else {
//Selection, enable buttons.
onbutton.setEnabled(true);
offbutton.setEnabled(true);
}
}
}
};
jl.addListSelectionListener(listSelectionListener);
// JScrollPane
JScrollPane listScroller = new JScrollPane(jl);
// JFrame
JFrame frame = new JFrame(file);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setExtendedState(frame.getExtendedState()|JFrame.MAXIMIZED_BOTH);
frame.addWindowListener(new WindowCloseHandler());
// Add and show
frame.getContentPane().add(listScroller, BorderLayout.CENTER);
frame.getContentPane().add(buttonPane, BorderLayout.PAGE_END);
frame.pack();
frame.setVisible(true);
}
private static class MyCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
@SuppressWarnings("rawtypes")
public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus ) {
Component c = super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
if ( annotations[index] == null ) {
c.setBackground( Color.white );
}
else if (annotations[index] == true) {
c.setBackground( Color.green );
} else {
c.setBackground( Color.red);
}
return c;
}
}
private static class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
int ind = jl.getSelectedIndex() +1;
if (e.getActionCommand().equals("on")) {
System.out.println("ON");
annotations[jl.getSelectedIndex()] = true;
}
if (e.getActionCommand().equals("off")) {
System.out.println("OFF");
annotations[jl.getSelectedIndex()] = false;
}
jl.clearSelection();
jl.setSelectedIndex(ind);
}
}
private static class WindowCloseHandler extends WindowAdapter {
public void windowClosing(WindowEvent evt) {
ObjectOutputStream save = null;
try {
save = new ObjectOutputStream(new FileOutputStream(file + "Annotations"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
save.writeObject(annotations);
} catch (IOException e) {
e.printStackTrace();
}
try {
save.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Saved.");
}
}
}
即使是jl.requestFocus();工作正常,我尝试了另一件让它起作用的东西:我交换了这两行
buttonPane.add(onbutton);
buttonPane.add(offbutton);
但是,为什么? 对不起,如果我再问一次,但这真的很奇怪,不是吗?
答案 0 :(得分:2)
在单元格渲染中,请尝试使用
if (annotations[index] == null) {
//c.setBackground(Color.white);
} else if (annotations[index] == true) {
c.setBackground(Color.green);
} else {
c.setBackground(Color.red);
}
对于“小”扩展的内容,您也可以尝试
private static class MyCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
private static final Border SELECTION_BORDER = new LineBorder(UIManager.getColor("List.selectionBackground"));
private static final Border EMPTY_BORDER = new EmptyBorder(1, 1, 1, 1);
@SuppressWarnings("rawtypes")
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setBorder(EMPTY_BORDER);
if (annotations[index] == null) {
if (isSelected) {
setBorder(SELECTION_BORDER);
}
c.setBackground(Color.white);
} else if (annotations[index] == true) {
c.setBackground(Color.green);
} else {
c.setBackground(Color.red);
}
return c;
}
}
基本上,您正在做的是更改选择突出显示颜色,隐藏选择。至于为什么你得到一个“似乎”突出显示所选行的油漆工件对我来说仍然是一个小秘密:P
更新了解原因
您有时得到的绘制工件是单元格渲染器的hasFocus
参数的结果,绘制了一个焦点矩形。
现在,如果您想保留现有的单元格渲染器,请在ActionEvent中尝试此操作
//jl.clearSelection();
jl.setSelectedIndex(ind);
jl.requestFocus();
从我所知道的情况来看,对于重新粉刷的经理来说,这似乎是微不足道的。如果我将jl.repaint()
添加到现有代码中(在setSelectedIndex
调用下),我可以让它永远不会绘制焦点矩形:P
答案 1 :(得分:2)
没有解决你的问题,没有解决问题,从不运行你的代码,只是将其拆分为逻辑块,添加最低要求的规则,抱歉最多5分钟
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
public class TweetsAnnotator {
private Boolean[] annotations = null;
private JList jl;
private JButton offbutton = new JButton("OFF Topic");
private JButton onbutton = new JButton("ON Topic");
private String file = "inception_TweetList";
private ArrayList<String> list;
private ObjectInputStream load;
private ObjectInputStream loadannot;
private ObjectOutputStream save;
public TweetsAnnotator() {// Read Tweets from file
loadDatas();
offbutton.setActionCommand("off"); // Buttons
offbutton.addActionListener(new ButtonListener());
offbutton.setEnabled(false);
onbutton.setActionCommand("on");
onbutton.addActionListener(new ButtonListener());
onbutton.setEnabled(false);
JPanel buttonPane = new JPanel(); // ButtonPanel
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
buttonPane.add(onbutton);
buttonPane.add(offbutton);
jl = new JList(list.toArray()); // JList
jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jl.setLayoutOrientation(JList.VERTICAL);
jl.setVisibleRowCount(-1);
jl.setCellRenderer(new MyCellRenderer());
ListSelectionListener listSelectionListener = new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (jl.getSelectedIndex() == -1) {
onbutton.setEnabled(false); //No selection, disable buttons.
offbutton.setEnabled(false);
} else {
onbutton.setEnabled(true); //Selection, enable buttons.
offbutton.setEnabled(true);
}
}
}
};
jl.addListSelectionListener(listSelectionListener);
JScrollPane listScroller = new JScrollPane(jl); // JScrollPane
JFrame frame = new JFrame(file); // JFrame
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.addWindowListener(new WindowCloseHandler());
frame.add(listScroller, BorderLayout.CENTER); // Add and show
frame.add(buttonPane, BorderLayout.PAGE_END);
frame.pack();
frame.setVisible(true);
}
private void loadDatas() {
try {
load = new ObjectInputStream(new FileInputStream(file));
list = (ArrayList<String>) load.readObject();
System.out.println(list.size() + " Tweets read from: " + file);
File fileannot = new File(file + "Annotations"); // Check and read annotations
if (fileannot.exists()) {
System.out.println("esiste, leggo");
loadannot = new ObjectInputStream(new FileInputStream(file + "Annotations"));
annotations = (Boolean[]) loadannot.readObject();
loadannot.close();
} else {
System.out.println("non esiste, creo poi leggo");
save = new ObjectOutputStream(new FileOutputStream(file + "Annotations"));
Boolean[] creatannotations = new Boolean[list.size()];
for (int i = 0; i < list.size(); i++) {
creatannotations[i] = (Boolean) null;
}
save.writeObject(creatannotations);
loadannot = new ObjectInputStream(new FileInputStream(file + "Annotations"));
annotations = (Boolean[]) loadannot.readObject();
}
System.out.println(annotations.length + " Annotations loaded");
} catch (IOException ex) {
ex.printStackTrace();
System.out.println(" Something wrong happened");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
System.out.println(" Something wrong happened");
} finally {
if (load != null) {
try {
load.close();
} catch (IOException ex) {
}
}
if (save != null) {
try {
save.close();
} catch (IOException ex) {
}
}
if (loadannot != null) {
try {
loadannot.close();
} catch (IOException ex) {
}
}
}
System.out.println("Load block ended");
}
private class MyCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (annotations[index] == null) {
c.setBackground(Color.white);
} else if (annotations[index] == true) {
c.setBackground(Color.green);
} else {
c.setBackground(Color.red);
}
return c;
}
}
private class ButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
int ind = jl.getSelectedIndex() + 1;
if (e.getActionCommand().equals("on")) {
System.out.println("ON");
annotations[jl.getSelectedIndex()] = true;
}
if (e.getActionCommand().equals("off")) {
System.out.println("OFF");
annotations[jl.getSelectedIndex()] = false;
}
jl.clearSelection();
jl.setSelectedIndex(ind);
}
}
private class WindowCloseHandler extends WindowAdapter {
@Override
public void windowClosing(WindowEvent evt) {
ObjectOutputStream save = null;
try {
save = new ObjectOutputStream(new FileOutputStream(file + "Annotations"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
save.writeObject(annotations);
} catch (IOException e) {
e.printStackTrace();
}
try {
save.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Saved.");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TweetsAnnotator tweetsAnnotator = new TweetsAnnotator();
}
});
}
}