简体   繁体   中英

Color individual JTable Cell based on content of cell?

Okay, I know this question has been asked a ton on stack overflow. I've read almost every article. I can absolutely not get this too work. I made a table that serves as an availability calendar for a hotel, and I would like to color cell's with 0 rooms available red, and ones with more than 0 green. I've tried implementing a table cell renderer at no avail. Here is all of my code. What am I doing wrong?

package gui;

import entity.Inventory;
import entity.Room;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import javax.swing.BorderFactory;

import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import tools.DateCalc;

public class Calendar extends JPanel {

    String[] years = {"2013", "2014"};
    JComboBox yearBox = new JComboBox(years);
    String[] months = {"January", "February", "March", "April", "May", "June", "July", "August",
        "September", "October", "November", "December"};
    JComboBox monthBox = new JComboBox(months);
    LinkedList<String> lTypes = Room.getRoomTypes();
    String[] types = lTypes.toArray(new String[0]);
    JComboBox typeBox = new JComboBox(types);

    CalendarModel model = new CalendarModel();
    JTable table = new JTable(model);

    public Calendar() {
        super();



        yearBox.setBounds(10, 10, 100, 30);
        yearBox.setSelectedIndex(0);
        yearBox.addItemListener(new ComboHandler());

        int selected = DateCalc.getNumMonth(DateCalc.getCurrentDate());

        monthBox.setSelectedIndex(selected);
        monthBox.addItemListener(new ComboHandler());
        // table.setBounds(10, 150, 550, 200);
        model.setMonth(Integer.parseInt((String)yearBox.getSelectedItem()), monthBox.getSelectedIndex(), 0);
        typeBox.addItemListener(new ComboHandler());
        add(monthBox);
        add(yearBox);
        add(typeBox);
        table.setGridColor(Color.black);
        table.setShowGrid(true);
        table.setRowHeight(40);
        table.setBorder(BorderFactory.createLineBorder(Color.black));

        table.setDefaultRenderer(String.class, new MyCellRender());
        add(table);



        setSize(600, 800);
        setVisible(true);
    }

    public static void main(String[] args) {
        Calendar app = new Calendar();
    }

    public class ComboHandler implements ItemListener {

        public void itemStateChanged(ItemEvent e) {

            model.setMonth(Integer.parseInt((String)yearBox.getSelectedItem()), monthBox.getSelectedIndex(), typeBox.getSelectedIndex());
            table.repaint();

        }
    }

    public class MyCellRender extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component c = super.getTableCellRendererComponent(table, value,
                                          isSelected, hasFocus,
                                          row, column);
            for (int i =0; i < 7; i++){
                for (int j = 0; j < j; j++){
                    String positive = (String)table.getModel().getValueAt(i,j);
                    System.out.println(positive);
                    int val = positive.indexOf(" 0 ");
                    if (val < 0)
                       c.setBackground(Color.green);
                    else{
                        c.setBackground(Color.red);
                    }
                }
            }

            return c;
        }
    }

    class CalendarModel extends DefaultTableModel {

        String[] days = {"  Sun", "  Mon", "  Tue", "  Wed", "  Thu", "  Fri", "  Sat"};
        int[] numDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        String[][] calendar = new String[7][7];

        public CalendarModel() {
            for (int i = 0; i < days.length; ++i) {
                calendar[0][i] = days[i];
            }
            for (int i = 1; i < 7; ++i) {
                for (int j = 0; j < 7; ++j) {
                    calendar[i][j] = " ";
                }
            }
        }

        @Override
        public boolean isCellEditable(int row, int column){
            return false;
        }
        public int getRowCount() {
            return 7;
        }

        public int getColumnCount() {
            return 7;
        }

        public String getValueAt(int row, int column) {
            return calendar[row][column];
        }

        public void setValueAt(String value, int row, int column) {
            calendar[row][column] = value;
        }

        public void setMonth(int year, int month, int flag) {
            for (int i = 1; i < 7; ++i) {
                for (int j = 0; j < 7; ++j) {
                    calendar[i][j] = " ";
                }
            }
            java.util.Calendar cal = java.util.Calendar.getInstance();
            cal.set(year, month, 1);
            Date date = cal.getTime();

            DateFormat df = new SimpleDateFormat("MMddyyyy");

            String start = df.format(date);
            int offset = cal.get(java.util.Calendar.DAY_OF_WEEK)-1;

            offset += 7;
            int num = daysInMonth(year, month);
            for (int i = 0; i < num; ++i) {
                String target = DateCalc.addDay(start, i);
                Inventory inventory = Inventory.fromDBObject(target);
                String type = (String)typeBox.getSelectedItem();
                String beds = inventory.getField(type);
                calendar[offset / 7][offset % 7] = "  " + Integer.toString(i + 1)
                        + ".  " + beds;
                ++offset;

            }
        }

        public boolean isLeapYear(int year) {
            if (year % 4 == 0) {
                return true;
            }
            return false;
        }

        public int daysInMonth(int year, int month) {
            int days = numDays[month];
            if (month == 1 && isLeapYear(year)) {
                ++days;
            }
            return days;
        }
    }
}

If the String class is used as the column class

table.setDefaultRenderer(String.class, new MyCellRender());

then, the column class of the TableModel should match:

@Override
public Class<?> getColumnClass(int columnIndex) {
   return String.class;
}

Also, there's an issue in getTableCellRendererComponent , in that the inner loop will not be executed

for (int i = 0; i < 7; i++) {
   for (int j = 0; j < j; j++) {
                   ^^^^^---------condition always false, loop will not execute

It's unclear why these loops are required as getTableCellRendererComponent is invoked for every cell component regardless.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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