【问题标题】:Accessing a JTextField in JTableHeader访问 JTableHeader 中的 JTextField
【发布时间】:2012-09-26 09:05:29
【问题描述】:

我制作了一个 TableHeader 渲染器,它将在 JTable 中的标题标签下创建一个 JTextfield。 我现在遇到的问题是,我从来没有在标题中获得焦点/访问这个 JTextfield。

我发现 TableHeader 渲染器只绘制组件而不做其余的事情,比如焦点和其他东西。

我尝试制作一个将设置在标题上的 JTextfield 数组,因此我可以在代码库中访问它们。不幸的是没有锻炼,我想知道是否有可能在标题中访问这个 JTextField,最好的方法是什么。

表头渲染器:

public class TextFieldTableHeaderRenderer extends AbstractCellEditor implements TableCellRenderer {

private MyPanel component;

public TextFieldTableHeaderRenderer(){
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    component = new MyPanel(column);
    ((MyPanel)component).setLabelText(value.toString());
    return component;
}

@Override
public Object getCellEditorValue() {
    return ((MyPanel)component).getTextField(); 
}

我的面板:

public class MyPanel extends JPanel {  

private javax.swing.JLabel label;
private javax.swing.JTextField textField;

public MyPanel(int column) {   
    super();   
    setLayout(new java.awt.BorderLayout());   
    label = new javax.swing.JLabel();   
    textField = new javax.swing.JTextField();  


    setBorder(javax.swing.BorderFactory.createEtchedBorder());

    label.setHorizontalAlignment(SwingConstants.CENTER);

    //textField.setText("Column "+column);

    add(textField, java.awt.BorderLayout.PAGE_END);

    add(label, java.awt.BorderLayout.CENTER);   
}   

public void setLabelText( String text ){
    label.setText(text);
}

public void setTextFieldText(String text){
    getTextField().setText(text);
}

public javax.swing.JTextField getTextField() {   
    return textField;   
}

/**
 * @param textField the textField to set
 */
public void setTextField(javax.swing.JTextField textField) {
    this.textField = textField;
}

在标题上安装:

for( int i=0; i < this.getxColumnModel().getColumnCount(); i++){
            this.getxColumnModel().getColumn(i, true).setHeaderRenderer( new TextFieldTableHeaderRenderer() );
        }

我尝试使用 i-net 中的“EditableHeader”示例,但单击标题时会生成一个新的 JTextfield。

我喜欢看到用户将注意力集中在 JTextfield 上,输入一个文本,然后它会过滤该列。

过滤不会有问题,因为我已经做到了。

希望我对你们很清楚,很想听听你们的解决方案

【问题讨论】:

  • 如果你想完成这项工作,你将有更多的工作要做。您不能以这种方式使用渲染器(这就是他们所说的“标记”)。你必须提供你的JTableHeader,它能够添加你需要的功能......
  • 感谢 MadProrammer!我将进一步了解 JTableHeaders。我开始使用它,但我不确定我是否需要它。
  • 你可以做一些小技巧,比如从表中“借用”表头并将其用作实现的一部分。
  • @d0n 不要为 JTableHeader 创建 CellEditor,用最简单的方法替换它来创建适当的 JTextField 数组
  • 如果您的意思是something like JYTable - 这是一项艰巨的工作,并非完全是微不足道的工作(我应该知道我写的:-)。所以你可能会考虑商业化(参考或替代品,f.i. JIDE)

标签: java swing jtable jtextfield jtableheader


【解决方案1】:

这是制作可编辑标题的简单方法:

编辑:哎呀-我打算在另一个线程中发布这个。我想我还是会把它留在这里。

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

public class JTableEditableHeaderDemo implements Runnable
{
  private JTable table;
  private JTableHeader header;
  private JPopupMenu renamePopup;
  private JTextField text;
  private TableColumn column;

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new JTableEditableHeaderDemo());
  }

  public JTableEditableHeaderDemo()
  {
    table = new JTable(10, 5);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setPreferredScrollableViewportSize(table.getPreferredSize());

    header = table.getTableHeader();
    header.addMouseListener(new MouseAdapter(){
      @Override
      public void mouseClicked(MouseEvent event)
      {
        if (event.getClickCount() == 2)
        {
          editColumnAt(event.getPoint());
        }
      }
    });

    text = new JTextField();
    text.setBorder(null);
    text.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e)
      {
        renameColumn();
      }
    });

    renamePopup = new JPopupMenu();
    renamePopup.setBorder(new MatteBorder(0, 1, 1, 1, Color.DARK_GRAY));
    renamePopup.add(text);
  }

  public void run()
  {
    JFrame f = new JFrame("Double-click header to edit");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().add(new JScrollPane(table));
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }

  private void editColumnAt(Point p)
  {
    int columnIndex = header.columnAtPoint(p);

    if (columnIndex != -1)
    {
      column = header.getColumnModel().getColumn(columnIndex);
      Rectangle columnRectangle = header.getHeaderRect(columnIndex);

      text.setText(column.getHeaderValue().toString());
      renamePopup.setPreferredSize(
          new Dimension(columnRectangle.width, columnRectangle.height - 1));
      renamePopup.show(header, columnRectangle.x, 0);

      text.requestFocusInWindow();
      text.selectAll();
    }
  }

  private void renameColumn()
  {
    column.setHeaderValue(text.getText());
    renamePopup.setVisible(false);
    header.repaint();
  }
}

【讨论】:

    【解决方案2】:

    TableColumn支持通过setHeaderRenderer()设置一个TableCellRenderer,如图example;它没有提供setHeaderEditor(),这是编辑所必需的。替代方案可能包括:

    • 写一个自定义JTableHeader。
    • 在相邻的等角布局中添加一行文本字段。
    • 按照FixedRowExample 中的建议,使用TableModel 中的特定行。
    • 考虑商业替代方案;列出了几个here。

    【讨论】:

    • +1 很好的选项总结。另一条路线 - 如 JIDE - 可能是将编辑器功能添加到标题中。他们都不是微不足道的(或者我很愚蠢:-)
    • @kleopatra:你从不愚蠢!我很感激你的cmets;以上。
    • 是的,我喜欢在标题中添加一个编辑器,因为它不存在。但不知道要开始:)。有什么建议可以看吗?
    • @kleopatra 您的带有标题的 JYTable 正是我想要的!
    • @kleopatra 刚刚通过您的网站向您发送了一封邮件。希望你能快点回答:)
    猜你喜欢
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多