手动/动态更改值时更新/调用JTable呈现 [英] Updating/Calling JTable rendering when a value is changed MANUALLY/DYNAMICALLY

查看:46
本文介绍了手动/动态更改值时更新/调用JTable呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我希望我的JTable每次在变量中的值更改时都呈现,但是这不会发生,仅当我单击它时将其呈现,或者将其移出视图然后再移回. ?我正在使用自定义的TableCellRender,如下所示.

so i want my JTable to render everytime a value in a variable is changed however this is not taking place, the table is only getting rendered either when I click on it, or move it out of view then back in. Any suggestions? I am using a custom TableCellRender as posted below.

import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;

public class myRenderer extends JLabel implements TableCellRenderer {

   private static final long serialVersionUID = 1L;

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

   @Override
   public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
           int row, int column) {
       setHorizontalAlignment(SwingConstants.CENTER);
       setText(value.toString());
       Color myColor = new Color(255, 253, 117);
       setBackground(myColor);
       if(value == Integer.valueOf(-1))
       {
           value = null;
           setText("");
           return this;
       } 
       for(int i = 0; i < 90; i++) {
           if(value == Integer.valueOf(finalClass.done[i])) //this value changes during the program.
           {
               setBackground(Color.cyan); 
           }
       }
       return this;
   }

}

我希望每次在程序的任何其他部分中更改finalClass.done中的值时,我的表都呈现出来.有任何想法吗?我尝试了revalidate选项,但没有结果.

I want my table to render everytime that the value in finalClass.done is changed in any other part of the program. any ideas? i tried the revalidate option, but got no results.

这是finalClass的最低版本,与上述渲染器代码一起运行时,它可以重现我面临的相同错误.

Here is a minimal version of finalClass, which when run together with the above mentioned renderer code, can reproduce the same error I'm facing.

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class finalClass {
    JFrame frame = new JFrame();
    static int[] done = new int[90];
    Integer[][] slip = new Integer[9][5];
    String colHeader[] = {"1","2","3","4","5"};
    JTable table;
    finalClass() {
        for(int i = 0; i<90; i++)
            done[i] = -1;
        int cnt = 0;
        for(int x = 0; x<9; x++ ) {
            for(int y = 0; y <5; y++) {
                slip[x][y] = cnt++;
            }
        }
        DefaultTableModel tableModel = new DefaultTableModel(slip, colHeader) {
            private static final long serialVersionUID = 1L;
            @Override
            public boolean isCellEditable(int row, int column) {
               //all cells false
               return false;
            }
        };
        table = new JTable(slip, colHeader);
        table.setDefaultRenderer(Object.class, new myRenderer());
        table.setModel(tableModel);
        frame.add(table);
        frame.setVisible(true);
        frame.pack();

    }
    public static void main(String[] args) {
        new finalClass();
        try {
        Thread.sleep(5000);
        done[5] = 10; 
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

在此先感谢大家与我保持联系.我是新来的,所以我可能要花一些时间才能了解这里的情况.很抱歉浪费您的时间,并感谢您的提前帮助.

Thank you all in advance for bearing with me. I'm new here so it might take a little time for me to understand how things are done around here. sorry to waste your time and thanks for the help in advance.

推荐答案

仅在移动表格或单击表格后才显示该值的原因是,这样做会强制重新绘制.
您可以通过在done[5] = 10;

The reason why the value shows only after you move the table or click on it, is that by doing so you force a repaint.
You can verify it by invoking frame.repaint() after done[5] = 10;

以下是一个文件的MRE(将整个代码复制粘贴到FinalClass.java中并运行):

The following is a one-file MRE (copy paste the entire code into FinalClass.java and run):

import java.awt.Color;
import java.awt.Component;
import java.util.Arrays;    
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class FinalClass {

    private final JFrame frame = new JFrame();
    private final int[] done = new int[90]; //better avoid static
    private final Integer[][] slip = new Integer[9][5];
    private final String colHeader[] = {"1","2","3","4","5"};
    private JTable table;

    FinalClass() {

        Arrays.fill(done, -1);
        int cnt = 0;
        for(int x = 0; x<9; x++ ) {
            for(int y = 0; y <5; y++) {
                slip[x][y] = cnt++;
            }
        }

        DefaultTableModel tableModel = new DefaultTableModel(slip, colHeader) {
            private static final long serialVersionUID = 1L;
            @Override
            public boolean isCellEditable(int row, int column) {
               //all cells false
               return false;
            }
        };

        table = new JTable(slip, colHeader);
        table.setDefaultRenderer(Object.class, new MyRenderer());
        table.setModel(tableModel);
        frame.add(table);
        frame.pack();
        frame.setVisible(true);
    }

    private void refresh(){
        frame.repaint();
    }

    void done(int index, int value){
        done[index] = value;
        refresh();
    }

    public static void main(String[] args) {

        FinalClass f = new FinalClass();
        try {
            Thread.sleep(3000);
            f.done(5, 10);
        } catch(Exception e) { e.printStackTrace(); }
    }

    //follow java naming conventions
    class MyRenderer extends JLabel implements TableCellRenderer {

           private static final long serialVersionUID = 1L;

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

           @Override
           public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
                   int row, int column) {
               setHorizontalAlignment(SwingConstants.CENTER);
               setText(value.toString());
               Color myColor = new Color(255, 253, 117);
               setBackground(myColor);
               if((int)value == -1)
               {
                   value = null;
                   setText("");
                   return this;
               }
               for(int i = 0; i < 90; i++) {
                   if((int)value == done[i]) //this value changes during the program.
                   {
                       setBackground(Color.cyan);
                   }
               }
               return this;
           }
        }
}


旁注:
1.如果您希望表自动响应不断变化的数据中的更改,则需要将更改应用于其模型,如此示例中所示回答您先前的问题.


Side notes:
1. If you want the table to respond automatically to change in the undelying data, you need to apply the change to its model as demonstrated in this answer to your previous question.

2.从多个线程修改done需要同步.
3.建议遵循 Java命名约定

2.Modifying done from more than one thread needs to be synchronized.
3.It is recommended to follow Java Naming Conventions

这篇关于手动/动态更改值时更新/调用JTable呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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