【问题标题】:How to dynamically update a JTable based on JComboBox values that are located in the same JPanel in Java?如何根据 Java 中位于同一 JPanel 中的 JComboBox 值动态更新 JTable?
【发布时间】:2020-12-29 12:28:21
【问题描述】:

我正在使用 JPanel 创建一个 JFrame,它有 2 个组合框:月份和年份选择。

然后在它们下面有一个基于 CalendarModel 的 JTable。 CalendarModel 的初始值基于第一个默认选择的月份和年份。

每次在每个组合框中选择不同的值时,如何动态更新表格?

我的代码(抱歉-尚未按类和方法排列)如下:

谢谢!

更新:我忘了添加 panel.add(scrollPane, BorderLayout.CENTER);

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Main {
    
    public static void main(String[] args) throws IOException {

        final Boolean[] isPressed = {false};
        
        JFrame frame = new JFrame("Timesheet creator");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 305);
        frame.setLocation(430, 100);
        
        JPanel panel = new JPanel();
        panel.setBackground( Color.ORANGE );
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // added code
        frame.add(panel);
        
        panel.add(new JLabel("\t")); // spacing label
        
        JLabel lbl = new JLabel("Select a month & year and click Create");
        lbl.setAlignmentX( Component.CENTER_ALIGNMENT);
        panel.add(lbl);
        
        panel.add(new JLabel("\t"));
        
        String[] monthsList = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
        Integer[] yearChoiceList = {2020,2021,2022,2023,2024,2025,2026,2027,2028,2028,2030};
        
        final JComboBox<String> cbMonth = new JComboBox<String>(monthsList);
        final JComboBox<Integer> cbYear = new JComboBox<Integer>(yearChoiceList);
        
        cbMonth.setMaximumSize(cbMonth.getPreferredSize());
        cbMonth.setAlignmentX(Component.CENTER_ALIGNMENT);
        cbMonth.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Month selected: " + cbMonth.getSelectedItem());
                CalendarModel model = new CalendarModel();
                model.setMonth(cbYear.getSelectedIndex() + 1998, cbMonth.getSelectedIndex());
            }
        } );
        panel.add(cbMonth);
        
        cbYear.setMaximumSize(cbYear.getPreferredSize());
        cbYear.setAlignmentX(Component.CENTER_ALIGNMENT);
        cbYear.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Year selected: " + cbYear.getSelectedItem());
                CalendarModel model = new CalendarModel();
                model.setMonth(cbYear.getSelectedIndex() + 1998, cbMonth.getSelectedIndex());
            }
        } );
        panel.add(cbYear);
        
        JButton btnCreate = new JButton("Create");
        btnCreate.setAlignmentX(Component.CENTER_ALIGNMENT); // added code
        btnCreate.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button pressed");
                isPressed[0] = true;
            }
        } );

        panel.setBorder( new EmptyBorder( 0,20,0,20 ) );
        panel.setSize( 150,60 );
        
        //Table creation:
        CalendarModel model = new CalendarModel();
        JTable table = new JTable(model);
        
        table.setBounds(130, 0, 80, 50);
        
        model.setMonth(cbYear.getSelectedIndex() + 1998, cbMonth.getSelectedIndex());
        model.fireTableDataChanged();
        table.setGridColor(Color.black);
        table.setShowGrid(true);
        table.setAlignmentX(Component.WIDTH);

        JScrollPane scrollPane = new JScrollPane(table);

        scrollPane.setBorder( new BevelBorder( 1 ) );
        scrollPane.setBorder( new EmptyBorder( 4,20,20,20 ) );
        scrollPane.setBackground( Color.ORANGE );
        scrollPane.getViewport().setViewPosition(new Point(50,50));
        scrollPane.setColumnHeaderView( table.getTableHeader() );
        scrollPane.getColumnHeader().setBackground( Color.ORANGE );
        table.getTableHeader().setVisible( false );

        panel.add(scrollPane, BorderLayout.CENTER);
        panel.add(btnCreate);
        frame.setVisible(true);
    }
}

CalendarModel 类:

import javax.swing.table.AbstractTableModel;

class CalendarModel extends AbstractTableModel {
    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] = " ";
    }
    
    public int getRowCount() {
        return 7;
    }
    
    public int getColumnCount() {
        return 7;
    }
    
    public Object getValueAt(int row, int column) {
        return calendar[row][column];
    }
    
    public void setValueAt(Object value, int row, int column) {
        calendar[row][column] = (String) value;
    }
    
    public void setMonth(int year, int month) {
        for (int i = 1; i < 7; ++i)
            for (int j = 0; j < 7; ++j)
                calendar[i][j] = " ";
        java.util.GregorianCalendar cal = new java.util.GregorianCalendar();
        cal.set(year, month, 1);
        int offset = cal.get(java.util.GregorianCalendar.DAY_OF_WEEK) - 1;
        offset += 7;
        int num = daysInMonth(year, month);
        for (int i = 0; i < num; ++i) {
            calendar[offset / 7][offset % 7] = Integer.toString(i + 1);
            ++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;
    }
}

【问题讨论】:

    标签: java swing model jtable jcombobox


    【解决方案1】:
    CalendarModel model = new CalendarModel();
    model.setMonth(cbYear.getSelectedIndex() + 1998, cbMonth.getSelectedIndex());
    

    上面的代码什么都不做。您创建了一个新模型并设置了月份,但不对模型执行任何操作。

    你有两个选择:

    1. 将表中的模型替换为新模型。

    代码:

    CalendarModel model = new CalendarModel();
    model.setMonth(cbYear.getSelectedIndex() + 1998, cbMonth.getSelectedIndex());
    table.setModel( model );
    
    1. 更新表中的现有模型以重置月份:

    代码:

    CalendarModel model = (CalendarModel)table.getModel();
    model.setMonth(cbYear.getSelectedIndex() + 1998, cbMonth.getSelectedIndex());
    

    在这两种情况下,这意味着您需要将 JTable 定义为类的实例变量,而不是局部变量。

    【讨论】:

    • @ShaiAlon 我确实举了一个例子。我怎样才能给你一个完整的例子?您发布的代码无法编译! 1) 我突出显示了错误的代码,并解释了为什么我认为它不正确。 2)然后我给了你两个可能的解决方案。看不懂的解释或者代码怎么办?
    • 对此我很抱歉,我认为已经足够了......我已经更新了帖子中的整个代码
    • 谢谢@camickr!!添加``` table.setModel(模型); ```确实解决了!非常感谢!
    猜你喜欢
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2013-02-24
    • 2021-11-17
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多