如何删除JTable的选定行(在第一列中有复选框)的文本?

Posted

技术标签:

【中文标题】如何删除JTable的选定行(在第一列中有复选框)的文本?【英文标题】:How to strikethrough text of a selected row(having checkbox in first column) of JTable? 【发布时间】:2011-07-13 17:30:30 【问题描述】:

我有一个 Jtable,第一列中有一个复选框。当复选框被选中时,我想删除一行的文本。 (例如,当我们的任务完成时,就像我们在 Microsoft Outlook 中所做的一样。)我尝试过使用 AttributeString,但无法做到。

谁能指导我解决它?

String strStrike; 
AttributedString as; 

public void setTextStrikeThrough() 
    for(int r=0;r< taskcells.length;r++) 
        if (ttable.getValueAt(r,0).equals(Boolean.TRUE))  
            for(int c=2;c<7;c++) 
                strStrike+=taskcells[r][c-1]; 
            //end inner for as=new
            AttributedString(strStrike); 
            as.addAttribute(TextAttribute.STRIKETHROUGH,
                TextAttribute.STRIKETHROUGH_ON);
            as.getIterator(); 
        //end if 
    //end for       

我不知道在哪里调用这个方法。我想在检查该行的复选框时删除一行的文本。

【问题讨论】:

你卡在哪里了? AttributedString 应该是要走的路。 我不知道如何将它用于 JTable。 可能在您的问题中包含一些代码行来说明您的问题。 好吧,我的意思是(并写了)这个问题。编辑您的问题并将格式化的代码放入其中并不难。请记住这一点,以防您在本网站上发布另一个问题。谢谢。 Yes..Thanks.. 我发现很难在这个评论回复部分格式化代码,否则我们可以在发布时看到我们问题的预览,所以在这种情况下,很容易格式化我们的代码.这里我看不到预览,这就是为什么不能编辑它。同时,我们都在用正确格式的代码编辑主要问题。谢谢。 【参考方案1】:

我不知道 ActionListener 是否适用于 JTable 中的 JCheckBox,因为复选框不是真正的按钮,而是复选框的呈现。也许玩桌子模型会有所帮助。例如,您可以使用 html 来显示表格单元格中显示的字符串的删除线。例如,下面我创建了一个自定义 TableModel,它扩展了 DefaultTableModel 并保存带有布尔对象的行,然后是我创建的 TextWrapper 类的对象,该对象根据布尔值更改其 toString 结果。

例如,

import java.util.Vector;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class StrikeThroughRow 
   public static final Object[][] DATA = Boolean.TRUE, "Monday", "fe",
      Boolean.FALSE, "Tuesday", "fi", Boolean.TRUE, "Wednesday", "fo",
      Boolean.FALSE, "Thursday", "fum", Boolean.TRUE, "Friday", "foo";

   public StrikeThroughRow() 

   

   private static void createAndShowUI() 
      JTable table = new JTable(new StrikeThroughModel(DATA));
      JScrollPane scrollpane = new JScrollPane(table);

      JFrame frame = new JFrame("StrikeThroughRow");
      frame.getContentPane().add(scrollpane);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   

   public static void main(String[] args) 
      java.awt.EventQueue.invokeLater(new Runnable() 
         public void run() 
            createAndShowUI();
         
      );
   


class StrikeThroughModel extends DefaultTableModel 
   public StrikeThroughModel(Object[][] data) 
      super(new String[]"Check", "Work Day", "Giant Speak", 0);
      for (int i = 0; i < data.length; i++) 
         Vector<Object> rowVect = new Vector<Object>();
         rowVect.add(data[i][0]);
         if (data[i].length > 1) 
            for (int j = 1; j < data[i].length; j++) 
               rowVect.add(new TextWrapper(data[i][j].toString(), (Boolean)data[i][0]));
            
         
         addRow(rowVect);
      
   

   @Override
   public Class<?> getColumnClass(int columnIndex) 
      if (columnIndex == 0) 
         return Boolean.class;
      
      return super.getColumnClass(columnIndex);
   

   @Override
   public void setValueAt(Object value, int row, int column) 
      if (column == 0) 
         for (int i = 1; i < getColumnCount(); i++) 
            TextWrapper textWrapper = (TextWrapper) getValueAt(row, i);
            textWrapper.setStrikeThrough((Boolean) value);
            fireTableCellUpdated(row, i);
         
      
      super.setValueAt(value, row, column);
   


class TextWrapper 
   private String text;
   private boolean strikeThrough = false;

   public TextWrapper(String text) 
      this.text = text;
   

   public TextWrapper(String text, boolean strikeThrough) 
      this(text);
      this.strikeThrough = strikeThrough;
   

   @Override
   public String toString() 
      if (strikeThrough) 
         return "<html><strike>" + text + "</html></strike>"; 
      
      return text;
   

   public void setStrikeThrough(boolean strikeThrough) 
      this.strikeThrough = strikeThrough;
   

我打赌会有更好的解决方案,包括为您的单元格创建自定义渲染器,但上面的代码提供了一个快速而肮脏的修复。

【讨论】:

谢谢..但是为什么它在 setValueAt(..) 方法中给了我这个错误??:"java.lang.ClassCastException: java.lang.String cannot be cast to practiceproblems.TextWrapper" at TextWrapper textWrapper = (TextWrapper) getValueAt(row, i);行。我使用的和你提到的一样,但使用的是 AbstractTableModel。 哦,因为 getValueAt(r,i) 返回 Object..但是我在使用 AbstractTableModel 时仍然无法做到这一点。仅使用试错法..有人可以用 AbstractTableModel 解释一下吗? 为什么不改用 DefaultTableModel?【参考方案2】:

以下是创建“删除线”的方法:

Map attributes = component.getFont().getAttributes();
attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
component.setFont( new Font(attributes) );

应用字体的一种方法是使用Table Row Rendering 方法。看一下背景颜色示例。您可以设置字体,而不是设置渲染器的背景。

否则,您需要为表格中的列创建自定义渲染器以使用适当的字体。

【讨论】:

【参考方案3】:

在复选框中添加一个侦听器,该复选框将从标签中添加/删除。以下是框和标签的示例,可能会有所帮助:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class check 
  public static void main(String args[]) 

    JFrame frame = new JFrame("for bsm");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JCheckBox box = new JCheckBox("check me");

    final JLabel label = new JLabel("<html>text</html>");
    label.setFont(new Font("helvetica", Font.PLAIN, 12));
    label.setForeground(new Color(50, 50, 25));

    ActionListener actionListener = new ActionListener() 
      public void actionPerformed(ActionEvent actionEvent) 
        AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
        if(abstractButton.getModel().isSelected())
            label.setText(label.getText().replace("<html>", "<html><strike>").replace("</html>", "</strike></html>"));
        else
            label.setText(label.getText().replace("<html><strike>", "<html>").replace("</strike></html>", "</html>"));
      
    ;

    box.addActionListener(actionListener);

    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout(10, 10));
    panel.add(label, BorderLayout.NORTH);
    panel.add(box, BorderLayout.SOUTH);
    panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

    frame.add(panel);
    frame.setSize(300, 200);
    frame.setVisible(true);
  

【讨论】:

以上是关于如何删除JTable的选定行(在第一列中有复选框)的文本?的主要内容,如果未能解决你的问题,请参考以下文章

R:在第一列中按重复项合并行

如何在第一列中只有最小元素的矩阵中查找行?

JTable 更改列字体

WPF中添加一个Datagrid使用dataset双向绑定,在第一列中添加一列checkbox用来选择本行,

Vue.js - 如何访问子组件的计算属性(Vuetify 数据表)

如果 AJAX 错误,请取消选中复选框 [重复]