如何正确使用TableCellRenderer对单元格进行颜色匹配

时间:2019-06-04 18:08:52

标签: java swing jtable

我正在开发一个程序,该程序从文件中读取数据并将其放入jTable中。 根据数据,我计算出BMI。 A

知道我正在尝试实现TableCellRenderer来为BMI列中的单元格着色。 颜色红色-当BMI> 25时 颜色:黄色-当BMI <18

这是我的 Renderer ,它是Frame的内部类:

public class BMIRenderer extends JPanel implements TableCellRenderer {

        public BMIRenderer() {
            super.setOpaque(true);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
                int row, int column) {

            Person p = (Person) value;

            if (p.getBMI() < 18) {
                super.setBackground(Color.YELLOW);
            } else if (p.getBMI() > 25) {
                setBackground(Color.RED);
            }

            return this;
        }
    }

将渲染器添加到jTable:

mainTable.setDefaultRenderer(Person.class, new BMIRenderer());

没有任何反应,我正在尝试通过扩展DefaultTableCellRenderer尝试不同的方法,但是您可以猜测输出是相同的。我认为此代码的语法中缺少某些内容。

这是框架的代码:

public class Frame extends JFrame {

    MyTableModel tableModel = new MyTableModel();
    JTable mainTable = new JTable();
    JPanel jPanel;
    JScrollPane scrollPane = new JScrollPane(mainTable);

    public Frame() throws ParseException, FileNotFoundException {
        this.setSize(new Dimension(500, 150));
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        mainTable.setDefaultRenderer(Person.class, new BMIRenderer());

        mainTable.setModel(tableModel);
        scrollPane.setVisible(true);

        jPanel = new JPanel(new BorderLayout());
        jPanel.setBorder(BorderFactory.createLineBorder(Color.black));
        jPanel.add(scrollPane, BorderLayout.CENTER);
        // this.pack();
        this.add(jPanel);

    public class BMIRenderer extends JLabel implements TableCellRenderer {

        public BMIRenderer() {
            super.setOpaque(true);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
                int row, int column) {

            Person p = (Person) value;

            if (p.getBMI() < 15) {
                super.setBackground(Color.YELLOW);
            } else if (p.getBMI() > 25) {
                setBackground(Color.RED);
            }

            return this;
        }
    }


    }

MyTableModel 类代码:

public class MyTableModel extends AbstractTableModel {

    ArrayList<Person> dataList;

    String imie, nazwisko;  //name, surname
    Color kolor;
    Integer wzrostCm, wagaKg; //weight, height
    Calendar cal;
    Person p;

    int BMI;
    int r, g, b;

    public MyTableModel() throws FileNotFoundException, ParseException {
        dataList = new ArrayList<Person>();

        Scanner read = new Scanner(new File("C:\\Users\\ziole\\EclipseWorkspace\\GUI_z07P_DOING\\src\\tabelka.txt"));

        String pattern = "yyyy-MM-dd";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);

        System.out.println("Wczytany plik:");
        while (read.hasNext()) {
            cal = Calendar.getInstance();
            String newLine = read.nextLine();
            String[] elements = newLine.split(" ");

            System.out.println(newLine);

            imie = elements[0];
            nazwisko = elements[1];

            Date date = simpleDateFormat.parse(elements[2]);
            cal.setTime(date);

            String[] RGB = elements[3].split(",");
            r = Integer.parseInt(RGB[0]);
            g = Integer.parseInt(RGB[1]);
            b = Integer.parseInt(RGB[2]);
            kolor = new Color(r, g, b);

            wzrostCm = new Integer(elements[4]);
            wagaKg = new Integer(elements[5]);

            BMI = bmi(wagaKg, wzrostCm);

            dataList.add(new Person(imie, nazwisko, kolor, wzrostCm, wagaKg, cal, BMI));
        }

    }

    @Override
    public int getColumnCount() {
        return 7;
    }

    @Override
    public int getRowCount() {
        return dataList.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {

        p = dataList.get(rowIndex);

        switch (columnIndex) {
        case 0:
            return p.imie;
        case 1:
            return p.nazwisko;
        case 2:
            return data(cal, p);
        case 3:
            return p.kolor.getRGB();
        case 4:
            return p.wzrostCm;
        case 5:
            return p.wagaKg;
        case 6:
            return p.BMI;

        }

        return null;
    }

    @Override
    public String getColumnName(int column) {
        switch (column) {
        case 0:
            return "Imie";
        case 1:
            return "Nazwisko";
        case 2:
            return "data";
        case 3:
            return "Kolor";
        case 4:
            return "Wzrost[cm]";
        case 5:
            return "Waga[kg]";
        case 6:
            return "BMI";
        }
        return null;
    }

    public String data(Calendar cal, Person p) {
        // po Galicyjsku
        switch (p.cal.get(cal.MONTH)) {
        case 0:
            return "xaneiro";
        case 1:
            return "febreiro";
        case 2:
            return "marzo";
        case 3:
            return "abril";
        case 4:
            return "maio";
        case 5:
            return "xuño";
        case 6:
            return "xullo";
        case 7:
            return "agosto";
        case 8:
            return "setembro";
        case 9:
            return "outubro";
        case 10:
            return "novembro";
        case 11:
            return "decembro";

        default:
            break;
        }
        return null;

    }

    public int bmi(Integer waga, Integer wzrostCm) {

        double wzrostKwadrat = (int) Math.pow(wzrostCm, 2);
        double wynik = Math.round(((waga / wzrostKwadrat) * 10000));
        return (int) wynik;

    }


}

人员班级:

public class Person {

    String imie, nazwisko;
    Color kolor;
    int r, g, b;
    Integer wzrostCm, wagaKg;
    Calendar cal;
    int BMI;

    public Person(String imie, String nazwisko, Color kolor, Integer wzrostCm, Integer wagaKg, Calendar cal, int BMI) {
        this.imie = imie;
        this.nazwisko = nazwisko;
        this.kolor = kolor;
        this.wzrostCm = wzrostCm;
        this.wagaKg = wagaKg;
        this.cal = cal;
        this.BMI = BMI;
    }
*here are simple getters and setters*
}

我从中读取的文件:

Jan Kowalski 1980-2-7 255,0,153 182 99
Michał Nowak 1988-8-13 0,0,153 177 73
Zofia Michalska 1971-6-12 255,0,51 162 53
Łukasz Gwózdz 1975-3-23 0,0,255 178 47
Tomasz Wójcik 1965-1-7 102,0,0 180 50
Beata Szczesniak 2000-8-28 51,102,0 160 70
Anna Pekala 1979-2-17 0,204,255 164 54
Robert Tarski 1971-11-2 255,102,0 176 70

在Main中,我只是创建框架的对象。

1 个答案:

答案 0 :(得分:2)

修改渲染器以扩展DefaultTableCellRenderer,重写getTableCellRendererComponent()方法:

import javax.swing.table.DefaultTableCellRenderer;

public class BMIRenderer extends DefaultTableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

        Person person = null;
        String bmiValue = "";
        if(value instanceof Person) {
            person = (Person)value;
            bmiValue = Integer.toString(person.getBMI());
        }

        //Pass just the bmiValue to the super method so the integer's toString() value is displayed
        super.getTableCellRendererComponent(table, bmiValue, isSelected, hasFocus, row, column);

        if(person != null) {
            if (person.getBMI() < 18) {
                super.setBackground(Color.YELLOW);
            } 
            else if (person.getBMI() > 25) {
                setBackground(Color.RED);
            }
        }

        return this;
    }
}

现在,修改表模型,使其返回第6列的整个Person对象,而不是BMI字段的int值:

@Override
public Object getValueAt(int rowIndex, int columnIndex) {

    Person person = dataList.get(rowIndex);

    switch (columnIndex) {
        case 0:
            return person.imie;
        case 1:
            return person.nazwisko;
        case 2:
            return data(cal, person);
        case 3:
            return person.kolor.getRGB();
        case 4:
            return person.wzrostCm;
        case 5:
            return person.wagaKg;
        case 6:
            //Return the entire Person object so that the column class matches to our custom cell renderer
            return person;

    }

    return null;
}

在MyTableModel类中,如下重写getColumnClass()方法:

@Override
public Class<?> getColumnClass(int columnIndex) {
    switch (columnIndex) {
        case 0:
            return String.class;
        case 1:
            return String.class;
        case 2:
            return String.class;
        case 3:
            return Integer.class;
        case 4:
            return Integer.class;
        case 5:
            return Integer.class;
        case 6:
            return Person.class;

    }
    return Object.class;
}
相关问题