简体   繁体   English

用jbutton突出显示JList

[英]JList highlight with jbutton

i coded a little annotator in Java with a simple GUI based on Swing but i faced with a problem that is freaking me out. 我用一个基于Swing的简单GUI在Java中编写了一个小注释器,但是我遇到了一个令我惊讶的问题。 The problem is: i have a jlist and two jbuttons modifying such jlist, the two buttons have the SAME listener but they don't work the same. 问题是:我有一个jlist和两个jbutton修改了这个jlist,这两个按钮具有相同的侦听器,但是它们的作用不同。 All it's supposed to work like this: once you select a row in the jlist you can tag it as ON TOPIC or OFF TOPIC (with the two buttons), the row changes color and then selects the next row but; 所有的工作都应该是这样的:一旦在jlist中选择了一行,就可以将其标记为ON TOPIC或OFF TOPIC(使用两个按钮),该行会更改颜色,然后选择下一行,但是; even if the selection is on the right row (the next one) it highlights the next just for the OFF Topic button, why? 即使选择位于右行(下一个),它也会突出显示仅用于“关闭主题”按钮的下一个,为什么?

Here's the code: 这是代码:

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.");
    }
}
}

Even though jl.requestFocus(); 即使jl.requestFocus(); works fine, i tried another thing that make it works: i swapped these two lines 工作正常,我尝试了另一件事,使它工作:我交换了这两行

buttonPane.add(onbutton);
buttonPane.add(offbutton);

but, why? 但为什么? Sorry if i ask again but it's really strange, isn't it? 对不起,如果我再问一次,那真的很奇怪,不是吗?

In your cell render, try this instead 在您的单元格渲染中,尝试使用此方法

if (annotations[index] == null) {
    //c.setBackground(Color.white);
} else if (annotations[index] == true) {
    c.setBackground(Color.green);
} else {
    c.setBackground(Color.red);
}

For something a "little" extended, you could also try 对于“小”扩展,您也可以尝试

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;
    }
}

Basically, what you are doing is changing the selection highlight color, hiding the selection. 基本上,您正在做的是更改选择突出显示颜色,隐藏选择。 As to why you did get a paint artifact that "seemed" to highlight the selected row is still a slight mystery to me :P 至于为什么您确实得到了一个“似乎”突出显示所选行的绘画工件,这对我来说仍然是个谜:P

UPDATED with Knowing why 知道原因后更新

The paint artifact you are sometimes getting is a result of the hasFocus parameter of the cell renderer, painting a focus rectangle. 有时会得到的绘制伪hasFocus单元格渲染器的hasFocus参数绘制的,它绘制了一个焦点矩形。

Now, if you want to keep your existing cell renderer, then try this in the ActionEvent 现在,如果要保留现有的单元格渲染器,请在ActionEvent中尝试

 //jl.clearSelection();
 jl.setSelectedIndex(ind);
 jl.requestFocus();

From what I can tell, it seems to a slight qwerk with the repaint manager. 据我所知,对于重绘管理器来说似乎有点奇怪。 If I added jl.repaint() into you existing code (under the setSelectedIndex call) I can get it to never paint the focus rectangle :P 如果我将jl.repaint()添加到您现有的代码中(在setSelectedIndex调用下),则可以使它永远不会绘制焦点矩形:P

not solving your quesion, not solved something, never to runs your code, just split that to the logics blocks, add minimum required rulles, sorry up-to 5 minutes 没有解决您的问题,没有解决问题,永远不要运行您的代码,只需将其拆分为逻辑块,添加所需的最低限度规则,最多可保留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();
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM