Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JTable中显示组件的最佳方式?_Java_Swing_Jtable_Jcomponent_Performance - Fatal编程技术网

Java 在JTable中显示组件的最佳方式?

Java 在JTable中显示组件的最佳方式?,java,swing,jtable,jcomponent,performance,Java,Swing,Jtable,Jcomponent,Performance,我不是问如何在JTable中显示组件,因为在线上有几个教程和示例。然而,我想知道最好的解决方法是什么 例如,我遇到的大多数教程都有创建单独类的示例(主类、扩展JTable的类、扩展TableModel的类、扩展TableCellRenderer的类等等)。但是,我发现您不能仅在一个类中执行此操作,而只需使用以下方法即可在一个方法中执行此操作: 示例代码(SSCCE) Main public class Main { public static void main(String[] args

我不是问如何在JTable中显示组件,因为在线上有几个教程和示例。然而,我想知道最好的解决方法是什么

例如,我遇到的大多数教程都有创建单独类的示例(主类、扩展
JTable
的类、扩展
TableModel
的类、扩展
TableCellRenderer
的类等等)。但是,我发现您不能仅在一个类中执行此操作,而只需使用以下方法即可在一个方法中执行此操作:

示例代码(SSCCE)
Main

public class Main
{
  public static void main(String[] args)
  {
    javax.swing.JFrame jf = new javax.swing.JFrame("A table with components");
    jf.setLayout(new java.awt.BorderLayout());
    jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    jf.add(new TableWithCompsPanel(), java.awt.BorderLayout.CENTER);
    jf.setVisible(true);
  }
}
带有组件的表格

public class TableWithCompsPanel extends java.awt.Container
{
  private Class<?> tableColumnClassArray[];
  private javax.swing.JTable jTableWithComps;
  private Object tableContentsArray[][];

  public TableWithCompsPanel()
  {
    tableContentsArray = new Object[][]
      {
        {"This is plain text",                                            new javax.swing.JButton("This is a button")    },
        {new javax.swing.JLabel("This is an improperly rendered label!"), new javax.swing.JCheckBox("This is a checkbox")}
      };
    tableColumnClassArray = new Class<?>[]{String.class, java.awt.Component.class};
    initGUI();
  }

  private void initGUI()
  {
    setLayout(new java.awt.BorderLayout());
    jTableWithComps = new javax.swing.JTable(new javax.swing.table.AbstractTableModel()
      {
        @Override public int getRowCount()
        {
          return tableContentsArray.length;
        }

        @Override public int getColumnCount()
        {
          return tableContentsArray[0].length;
        }

        @Override public Object getValueAt(int rowIndex, int columnIndex)
        {
          return tableContentsArray[rowIndex][columnIndex];
        }

        @Override public Class<?> getColumnClass(int columnIndex)
        {
          return tableColumnClassArray[columnIndex];
        }
      });
    jTableWithComps.setDefaultRenderer(java.awt.Component.class, new javax.swing.table.TableCellRenderer()
    {
      @Override public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
      {
        return value instanceof java.awt.Component ? (java.awt.Component)value : new javax.swing.table.DefaultTableCellRenderer();
      }
    });
    add(jTableWithComps, java.awt.BorderLayout.CENTER);
  }
}
public class TableWithCompsPanel扩展了java.awt.Container
{
私有类tableColumnClassArray[];
私有javax.swing.JTable jTableWithComps;
私有对象tableContentsArray[];
公共表WithCompspanel()
{
tableContentsArray=新对象[][]
{
{“这是纯文本”,新的javax.swing.JButton(“这是一个按钮”)},
{new javax.swing.JLabel(“这是一个不正确呈现的标签!”),new javax.swing.JCheckBox(“这是一个复选框”)}
};
tableColumnClassArray=新类[]{String.Class,java.awt.Component.Class};
initGUI();
}
私有void initGUI()
{
setLayout(新java.awt.BorderLayout());
jTableWithComps=newjavax.swing.JTable(newjavax.swing.table.AbstractTableModel()
{
@重写公共int getRowCount()
{
返回tableContentsArray.length;
}
@重写公共int getColumnCount()
{
返回tableContentsArray[0]。长度;
}
@重写公共对象getValueAt(int-rowIndex,int-columnIndex)
{
返回tableContentsArray[rowIndex][columnIndex];
}
@重写公共类getColumnClass(int columnIndex)
{
返回tableColumnClassArray[columnIndex];
}
});
jTableWithComps.setDefaultRenderer(java.awt.Component.class,新的javax.swing.table.TableCellRenderer())
{
@重写公共java.awt.Component gettableCellRenderComponent(javax.swing.JTable表、对象值、布尔isSelected、布尔hasFocus、int行、int列)
{
返回值instanceof java.awt.Component?(java.awt.Component)值:new javax.swing.table.DefaultTableCellRenderer();
}
});
添加(jTableWithComps、java.awt.BorderLayout.CENTER);
}
}
问题:
我想知道的是,如果它可以在这么短的代码量内完成,为什么示例会不厌其烦地将它分成三个类,有时甚至更多的类?我的代码在运行时是否效率较低?我可以理解将主类和具有示例GUI的类分开,但不理解为什么要将示例GUI分成几个类

编辑:我看到很多人给出了这个代码不实用的理由。如果您能提供一个替代方案,我将更加感谢您的回答

  • 渲染器
    仅用于直观地装饰单元格内容,例如setFont、setForeground、setBackground、isEnable、isVisible等

  • 运行时,不要在
    渲染器中创建、设置、更改
    JComponents
    类型;这是
    TableModel
    的作业

  • 如果可能,请使用
    DefaultTableModel
    并利用现有渲染器进行渲染

  • 您已经知道
    JTable
    的单元格中存在哪些
    Object/JComponent


  • 需要考虑的一些事情:

    • 从您的示例来看,单元格值似乎是一个组件。对于每一个非平凡的表来说,这不是需要巨大的内存吗
    • 当选定行、处于焦点等时,组件是否正确绘制
    • 除非您的组件非常智能,否则您可能无法使单元格可编辑

    一般来说,如此多的交互组件的划分是因为设计。这种设计试图应用好的原则,比如分离关注点。你可以建立一个大的东西,做任何事情,或确定较小的部分,每个人都有责任感。在后一种情况下,您的代码更适合更改,因为每个类只做一件事,并且更改很多时间意味着在不破坏解决方案的一般体系结构的情况下涉及一两项职责

    特别是Swing应用的MVC模式有点冗长,但试图掌握很多好的设计原则。我知道维护它并不总是最简单的事情,但我必须认识到责任是非常解耦的

    样品可能很短。但他们必须坚持Swing的理念和架构。这就是为什么它们独立于代码的大小实现相同的角色

    这方面的经验法则(IMHO)是为每个划分找到划分的原因

    性能:如果代码被分成几个类,不要担心。这不会影响性能。其他事情(比如时间复杂度)也会这样做。或者可能是组件使用不当,但如果所有组件都按预期用途使用,则一切正常


    编辑:希望这个答案有用!正如您所看到的,它根本不是面向swing的…

    出于内存效率的考虑,
    TableModel
    以尽可能最简单的方式对要跟踪的数据进行建模。
    TableCellRenderer
    定义了如何在表格单元格中显示该数据

    在iTunes复选框示例中,从复选框建模信息的最简单方法是布尔值(真/假)。存储10000个
    boolean
    对象的集合比存储10000个
    JCheckBox
    对象的集合的内存效率要高得多

    然后,
    TableCellRenderer
    可以存储单个
    JCheckBox
    对象,当请求它提供一个compo时