创建一个右侧有链接的JTable

时间:2013-11-19 21:29:30

标签: java swing jframe

我正在开发一个工作项目,我输入一个日志文件,根据它解析它 日志中的线程并将完整的线程确认放在JTable中。对于每个线程,如果特定列中存在错误或正常消息,则显示为红色或蓝色。我已经实现了这个。我的项目的下一步是在GUI的右侧实现一个栏,它将显示您可以单击的链接,它将转到JTable的那一行。

这方面的一个很好的例子是NetBeans IDE。当你看着 主窗口,你选择任何变量,右边有一个栏显示 该变量的出现。这是我需要实现的想法。

编辑: 这是一个较新的版本,我正在使用教程中的示例。我所做的是创建3个“元素”窗格(当然每个窗格都有自己的布局管理器),然后将它们添加到边框布局管理器中。这部分工作正常。我遇到的问题是否有问题我可以将JTable改为行高,因为gui的大小会改变(全屏或更小)。

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package testcolumnheadings;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.JOptionPane;
import javax.swing.event.*;
import javax.swing.table.*;
import testcolumnheadings.TestColumnHeadings.Status;
import static testcolumnheadings.TestColumnHeadings.table;

public class TestColumnHeadings extends JPanel {

    enum Status {SELECTED, DESELECTED, INDETERMINATE}
    DefaultTableModel model = null;
    static JTable table = null;
    static JTable jbl = null;
    static JFileChooser fileChooser;
    static File prtFile = null;
    static String prtFilePath = null;

    public TestColumnHeadings(){
        super (new BorderLayout());
        Object[] columnNames = {Status.INDETERMINATE, "Integer", "String"};
        Object[][] data = {{true, 1, "BBB"}, {false, 12, "AAA"}, 
            {true, 2, "DDD"}, {false, 5, "CCC"},
            {true, 3, "EEE"}, {false, 6, "GGG"},
            {true, 4, "FFF"}, {false, 7, "HHH"},
            {true, 1, "III"}, {false, 312, "JJJ"}, 
            {true, 12, "KKK"}, {false, 75, "LLL"},
            {true, 2, "DDD"}, {false, 5, "CCC"},
            {true, 3, "EEE"}, {false, 6, "GGG"},
            {true, 4, "FFF"}, {false, 7, "HHH"},
            {true, 1, "III"}, {false, 312, "JJJ"}, 
            {true, 12, "KKK"}, {false, 75, "LLL"},
            {true, 2, "DDD"}, {false, 5, "CCC"},
            {true, 3, "EEE"}, {false, 6, "GGG"},
            {true, 4, "FFF"}, {false, 7, "HHH"},
            {true, 1, "III"}, {false, 312, "JJJ"}, 
            {true, 12, "KKK"}, {false, 75, "LLL"},
            {true, 13, "MMM"}, {false, 46, "NNN"},
            {true, 14, "OOO"}, {true, 67, "PPP"},
            {true, 11, "QQQ"}, {false, 112, "RRR"}, 
            {true, 22, "SSS"}, {false, 35, "TTT"},
            {true, 23, "UUU"}, {false, 56, "VVV"},
            {true, 24, "WWW"}, {true, 97, "XXX"}};
        model = new DefaultTableModel(data, columnNames){
            @Override
            public Class<?> getColumnClass(int column){
                return getValueAt(0, column).getClass();
            }
        };

        table = new JTable(model){           
            @Override
            public void updateUI(){
                super.updateUI();

                TableCellRenderer r = getDefaultRenderer(Boolean.class);
                if(r instanceof JComponent){
                    ((JComponent)r).updateUI();
                }
            }
            @Override
            public Component prepareEditor (TableCellEditor editor, int row, int column){
                Component c = super.prepareEditor(editor, row, column);
                if (c instanceof JCheckBox){
                    JCheckBox b = (JCheckBox)c;
                    b.setBackground(getSelectionBackground());
                    b.setBorderPainted(true);
                }
                return c;
            }
        };

        int modelColumnIndex = 0;
        TableCellRenderer renderer = new HeaderRenderer (table.getTableHeader(), modelColumnIndex);

        table.getColumnModel().getColumn(modelColumnIndex).setHeaderRenderer(renderer);

        model.addTableModelListener(new HeaderCheckBoxHandler(table, modelColumnIndex));

        add(new JScrollPane(table));
        setPreferredSize (new Dimension(320, 240));
    }


    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run(){
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI() {
        try{
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e){
            e.printStackTrace();
        }
        JFrame frame = new JFrame ("Table Header Check Box");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        TestColumnHeadings tstHead = new TestColumnHeadings();

        JPanel p1 = new JPanel();
        p1.setLayout(new BorderLayout());
        p1.add(tstHead);

        jbl = new JTable(table.getRowCount(), 1);
        jbl.setRowHeight(6);
        jbl.getColumnModel().getColumn(0).setMaxWidth(6);
//        jbl.;

        JPanel p2 = new JPanel(new BorderLayout());
        p2.add(jbl, BorderLayout.CENTER);

        JButton btn = new JButton("Save Selection");
        btn.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent ae) {
                int i, j;
                boolean row;
                String selected = null;
                JLabel lbl = new JLabel();

                for (i = 0; i < table.getRowCount(); i ++){

                    row = (boolean)table.getValueAt(i, 0);
                    if (row){
                        if (selected == null){
                            selected = (String)(i + " " + table.getValueAt(i, 1) + " " + table.getValueAt(i, 2) + "\n");
                        }
                        else{
                            selected += (String)(i + " " + table.getValueAt(i, 1) + " " + table.getValueAt(i, 2) + "\n");
                        }
                    }
                }
                fileChooser = new JFileChooser();
                fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                j = fileChooser.showSaveDialog(new JFileChooser());

                if (j == JFileChooser.APPROVE_OPTION){
                    prtFile = fileChooser.getSelectedFile();
                    prtFilePath = prtFile.getAbsolutePath();
                    System.out.println("Save File Selected: " + prtFilePath);
                    try {
                        try (FileWriter fw = new FileWriter(prtFile)) {
                            fw.write(selected);
                        }
                        JOptionPane.showMessageDialog(new JOptionPane(), "File saved completed.");
                    } catch (IOException ex) {
                        Logger.getLogger(TestColumnHeadings.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        });

        JPanel p3 = new JPanel(new FlowLayout (FlowLayout.RIGHT));
        p3.add(btn, BorderLayout.SOUTH);

        frame.add(p1, BorderLayout.CENTER);
        frame.add(p2, BorderLayout.EAST);
        frame.add(p3, BorderLayout.SOUTH);

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }


    public class StatusColumnCellRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
            JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

            l.setBackground(Color.WHITE);
            l.setForeground(Color.BLACK);

            if (table.getValueAt(0, row).equals(true)){
                l.setForeground(Color.WHITE);
                l.setBackground(Color.RED);
            }
            else {
                l.setForeground(Color.WHITE);
                l.setBackground(Color.CYAN);
            }
            return l;
        }
    }
}

class HeaderRenderer extends JCheckBox implements TableCellRenderer {
    private final JLabel label = new JLabel ("Check All");
    private int targetColumnIndex;

    public HeaderRenderer (JTableHeader header, int index){
        super ((String)null);
        this.targetColumnIndex = index;
        setOpaque(false);
        setFont(header.getFont());
        header.addMouseListener(new MouseAdapter(){
            @Override
            public void mouseClicked (MouseEvent e){
                JTableHeader header = (JTableHeader)e.getSource();
                JTable table = header.getTable();
                TableColumnModel columnModel = table.getColumnModel();
                int vci = columnModel.getColumnIndexAtX(e.getX());
                int mci = table.convertColumnIndexToModel(vci);
                if (mci == targetColumnIndex){
                    TableColumn column = columnModel.getColumn(vci);
                    Object v = column.getHeaderValue();
                    boolean b = Status.DESELECTED.equals(v);
                    TableModel m = table.getModel();
                    column.setHeaderValue(b ? Status.SELECTED : Status.DESELECTED);
                    for (int i = 0; i < m.getRowCount(); i++){
                            table.setValueAt(b, i, 0);
                    }
                    header.repaint();                    
                }
            }
        });
    }
    @Override
    public Component getTableCellRendererComponent (JTable tbl, Object val, boolean isS, boolean hasF, int row, int col){
        TableCellRenderer r = tbl.getTableHeader().getDefaultRenderer();
        JLabel l = (JLabel)r.getTableCellRendererComponent(tbl, val, isS, hasF, col, col);
        if (targetColumnIndex == tbl.convertColumnIndexToModel(col)){
            if (val instanceof Status){
                switch ((Status) val){
                    case SELECTED:
                        setSelected(true);
                        setEnabled(true);
                        break;
                    case DESELECTED:
                        setSelected(false);
                        setEnabled(true);
                        break;
                    case INDETERMINATE:
                        setSelected(true);
                        setEnabled(false);
                        break;
                }
            }else{
                setSelected(true);
                setEnabled(false);
            }
            label.setIcon(new ComponentIcon(this));
            l.setIcon(new ComponentIcon(label));
            l.setText(null);
        }

        return l;
    }
    @Override
    public void updateUI(){
        setText(null); 
        super.updateUI();
    }
}

class HeaderCheckBoxHandler implements TableModelListener {
    private final JTable table;
    private final int targetColumnIndex;

    public HeaderCheckBoxHandler (JTable table, int index){
        this.table = table;
        this.targetColumnIndex = index;
    }
    @Override
    public void tableChanged (TableModelEvent e){
        if (e.getType() == TableModelEvent.UPDATE && e.getColumn() == targetColumnIndex){
            int vci = table.convertColumnIndexToView(targetColumnIndex);
            TableColumn column = table.getColumnModel().getColumn(vci);
            if (!Status.INDETERMINATE.equals(column.getHeaderValue())){
                column.setHeaderValue(Status.INDETERMINATE);
            } else{
                boolean selected = true, deselected = true;
                TableModel m = table.getModel();
                for (int i = 0; i < m.getRowCount(); i ++){
                    Boolean b = (Boolean)m.getValueAt(i, targetColumnIndex);
                    selected &= b;
                    deselected &= !b;
                    if (selected == deselected)
                        return;
                }
                if (selected){
                    column.setHeaderValue(Status.SELECTED);

                }else if (deselected){
                    column.setHeaderValue(Status.DESELECTED);
                }else{
                    return;
                }
            }
            JTableHeader h = table.getTableHeader();
            h.repaint(h.getHeaderRect(vci));
        }
    }
}

class ComponentIcon implements Icon {
    private final JComponent cmp;

    public ComponentIcon(JComponent cmp){
        this.cmp = cmp;
    }

    @Override
    public int getIconWidth(){
        return cmp.getPreferredSize().width;
    }

    @Override
    public int getIconHeight(){
        return cmp.getPreferredSize().height;
    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y){
        SwingUtilities.paintComponent(g, cmp, (Container)c, x, y, getIconWidth(), getIconHeight());
    }
}

1 个答案:

答案 0 :(得分:0)

我认为你需要这样的事情

enter image description here

在左边你有你的桌子,在右边你有Panel有信息。我使用BorderLayout,阅读tutorial。在riht面板中,您可以为链接编写逻辑,这些链接可以是t.editCellAt(a)或其他内容。和代码:

public class Form extends JFrame {

    public Form() {
        DefaultTableModel model;
        final JTable t = new JTable(model = new DefaultTableModel(new Object[][]{},new Object[]{1,2,3,4,5}));
        for(int i =0;i<10;i++){
            model.addRow(new Object[]{i,i,i,i,i});
        }
        JScrollPane jsp = new JScrollPane(t);
        final RightPanel right = new RightPanel();
        t.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent arg0) {
                right.col.setText("Col " + t.getSelectedColumn());
                right.row.setText("Row " + t.getSelectedRow());
                if(t.getSelectedColumn() != -1 && t.getSelectedRow() != -1){
                    right.text.setText("Value " + t.getValueAt(t.getSelectedRow(),t.getSelectedColumn()));
                }
            }
        });
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(jsp, BorderLayout.CENTER);
        add(right, BorderLayout.EAST);
        pack();
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new Form().setVisible(true);
            }
        });
    }

    class RightPanel extends JPanel{

        JLabel row;
        JLabel col;
        JLabel text;

        public RightPanel(){
            setLayout(new GridBagLayout());
            GridBagConstraints c = new GridBagConstraints();
            c.insets = new Insets(5, 5, 5, 5);
            JLabel l = new JLabel("Option Panel");
            c.gridy = 0;
            add(l,c);
            row = new JLabel("2");
            c.gridy++;
            add(row,c);
            col = new JLabel("3");
            c.gridy++;
            add(col,c);
            text = new JLabel("4");
            c.gridy++;
            add(text,c);
        }

    }
}