如何使JLabel在运行时JTable列交换后仍然出现? [英] How to make JLabel still appear after JTable column swap in the runtime?

查看:55
本文介绍了如何使JLabel在运行时JTable列交换后仍然出现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JTable:

不幸的是,在我交换列之后,不再显示标志:

after I swap columns unfortunately the flags are not rendered anymore:

我认为这是我的getColumnClass方法的错,在我的每列中都有固定的类,但是我不知道如何解决此问题.

I assume it is the fault of my getColumnClass method where I have fixed class for every column, but I don't know how to fix this issue.

package zad1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Arrays;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

public class CountryTable extends JTable {




    public CountryTable(String countriesFileName) {
        Vector<String> columnNames = new Vector<String>();
        Vector<Vector<Object>> data = new Vector<Vector<Object>>();
        try {
            BufferedReader br = new BufferedReader(new FileReader(countriesFileName));
            columnNames.addAll(Arrays.asList(br.readLine().split("\t")));
            System.out.println(columnNames);
            String line;
            while ((line = br.readLine()) != null) {
                String[] attributes = line.split("\t");
                Vector<Object> rowData = new Vector<Object>();
                rowData.add(attributes[0]);
                rowData.add(attributes[1]);
                rowData.add(Long.valueOf(attributes[2]));
                BufferedImage icon = ImageIO.read(new File("./data/" + attributes[3]));
                double ratio = (double) icon.getWidth() / icon.getHeight();
                rowData.add(new ImageIcon(icon.getScaledInstance(30, 20, Image.SCALE_FAST)));
                data.add(rowData);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        setModel(new MyTableModel(data, columnNames));
        setRowHeight(30);
        getColumnModel().getColumn(2).setCellRenderer(new PopulationCellRenderer());
        for (int i = 0; i < getColumnCount(); i++) {
            getColumnModel().getColumn(i).setWidth(400);
        }
    }

    @Override
    public Class getColumnClass(int column) {
        switch (column) {
        case 0:
            return String.class;// Panstwo
        case 1:
            return String.class;// stolica
        case 2:
            return Long.class;// ludnosc
        case 3:
            return Icon.class; // flaga jakiej klasy jest dana komorka w danej kolumnie aby tabela ja poprawnie wyswietlila
        default:
            return String.class;
        }
    }


    class MyTableModel extends DefaultTableModel {
        public MyTableModel(Vector<Vector<Object>> data, Vector<String> columnNames) {
            super(data, columnNames);//wywolanie konstruktora z nadklasy
            System.out.println(columnNames);
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return column == 3;
        }
    }

    class PopulationCellRenderer extends JLabel implements TableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Long population = (Long) value;
            setHorizontalAlignment(JLabel.RIGHT);
            if (population > 20000000) {
                setForeground(Color.red);
            } else {
                setForeground(Color.BLACK);
            }
            setText(population + "");
            return this;
        }

    }
}

推荐答案

无需为此扩展JTable.您的示例在模型中应该覆盖视图中的getColumnClass().适用于Icon.class默认渲染器列移动到的任何地方.

There's no need to extend JTable for this. Your example overrides getColumnClass() in the view, when it should do so in the model. The default renderer for Icon.class will be applied wherever the column is moved.

private final TableModel model = new DefaultTableModel(data, columnNames) {

    @Override
    public Class<?> getColumnClass(int column) {
        switch (column) {
             …
        }
    }
};

这也将使按类型应用PopulationCellRenderer成为可能:

This will also make it possible to apply the PopulationCellRenderer on a per-type basis:

table.setDefaultRenderer(Long.class, new PopulationRenderer());

还考虑扩展DefaultTableCellRenderer,如此处,使用NumberFormat,如下所示.根据@mKorbel的示例,下面的自包含代码显示了已更正的TableModel和已更新的TableCellRenderer.

Also consider extending DefaultTableCellRenderer, as shown here, using a NumberFormat, as shown below. Based on an example by @mKorbel, the self-contained code below shows a corrected TableModel and updated TableCellRenderer.

import java.awt.*;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.table.*;

public class TableExample {

    private static final long CUSP = 20000000;
    private JFrame frame = new JFrame("Table Demo");
    private Icon errorIcon = (Icon) UIManager.getIcon("OptionPane.errorIcon");
    private Icon infoIcon = (Icon) UIManager.getIcon("OptionPane.informationIcon");
    private Icon warnIcon = (Icon) UIManager.getIcon("OptionPane.warningIcon");
    private String[] columnNames = {"String", "Long", "Float", "Double", "Boolean", "Icon"};
    private Object[][] data = {
        {"aaa", CUSP - 1, 12.15F, 100.05, true, (errorIcon)},
        {"bbb", CUSP, 7.154F, 6.1555, false, (infoIcon)},
        {"ccc", CUSP + 1, 0.1135F, 3.1455, true, (warnIcon)},
        {"ddd", 42L, 31.15F, 10.05, true, (errorIcon)},
        {"eee", 12345L, 5.154F, 16.1555, false, (infoIcon)},
        {"fff", 54321L, 4.1135F, 31.1455, true, (warnIcon)}};
    private final TableModel model = new DefaultTableModel(data, columnNames) {

        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
                case 0:
                    return String.class;
                case 1:
                    return Long.class;
                case 2:
                    return Float.class;
                case 3:
                    return Double.class;
                case 4:
                    return Boolean.class;
                case 5:
                    return Icon.class;
                default:
                    return String.class;
            }
        }
    };
    private final JTable table = new JTable(model);

    private static class PopulationRenderer extends DefaultTableCellRenderer {

        NumberFormat f = NumberFormat.getInstance();

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int col) {
            JLabel r = (JLabel) super.getTableCellRendererComponent(
                table, value, isSelected, hasFocus, row, col);
            if (col == 1) {
                r.setHorizontalAlignment(JLabel.RIGHT);
                Long population = (Long) value;
                if (population > CUSP) {
                    r.setForeground(Color.red);
                } else {
                    r.setForeground(Color.BLACK);
                }
                r.setText(f.format(population));
            }
            return r;
        }
    }

    public TableExample() {
        int h = infoIcon.getIconHeight();
        table.setRowHeight(h);
        table.setPreferredScrollableViewportSize(
            new Dimension(table.getPreferredSize().width, 4 * h));
        table.setAutoCreateRowSorter(true);
        table.setDefaultRenderer(Long.class, new PopulationRenderer());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            TableExample tableExample = new TableExample();
        });
    }
}

这篇关于如何使JLabel在运行时JTable列交换后仍然出现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆