Как зачеркнуть текст выбранной строки (с флажком в первом столбце) JTable?

У меня есть 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       
}

Я не понимаю, где именно вызывать этот метод. Я хочу зачеркнуть текст строки, когда установлен флажок этой строки.


person bsm    schedule 11.03.2011    source источник
comment
Где ты застрял? AttributedString должен быть путь.   -  person miku    schedule 11.03.2011
comment
Я не понимаю, как именно использовать его для JTable.   -  person bsm    schedule 11.03.2011
comment
Возможно, включите в свой вопрос несколько строк кода, которые иллюстрируют вашу проблему.   -  person miku    schedule 11.03.2011
comment
Ну я имел в виду (и написал) в вопросе. Нетрудно отредактировать ваш вопрос и поместить в него отформатированный код. Пожалуйста, имейте это в виду, если вы разместите еще один вопрос на этом сайте. Спасибо.   -  person miku    schedule 11.03.2011
comment
Да..Спасибо..Мне было сложно отформатировать код в этом разделе ответов на комментарии, иначе мы можем увидеть предварительный просмотр нашего вопроса во время публикации, поэтому в этом случае наш код легко отформатировать. Здесь я не мог видеть предварительный просмотр, вот и все. почему не удалось его отредактировать. В то же время мы оба редактировали основной вопрос с правильно отформатированным кодом. Спасибо.   -  person bsm    schedule 11.03.2011


Ответы (3)


Я не знаю, будет ли ActionListener хорошо работать для JCheckBox в JTable, поскольку флажок не является реальной кнопкой, а скорее визуализацией флажка. Возможно, игра с моделью стола поможет. Например, вы можете использовать HTML для отображения перечеркнутых строк, отображаемых в ячейках таблицы. Например, ниже я создаю пользовательскую TableModel, которая расширяет DefaultTableModel и содержит строки с логическим объектом, за которым следуют объекты класса TextWrapper, который я создал, который изменяет свой результат toString в зависимости от логического значения.

e.g.,

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;
   }
}

Бьюсь об заклад, что есть лучшие решения, включая создание собственного средства визуализации для ваших ячеек, но приведенный выше код предлагает быстрое и грязное решение.

person Hovercraft Full Of Eels    schedule 11.03.2011
comment
Спасибо .. Но почему он дает мне эту ошибку в методе setValueAt (..)??: java.lang.ClassCastException: java.lang.String не может быть приведен к практическим проблемам. ); line. Я использовал то же, что и вы, но использовал AbstractTableModel. - person bsm; 16.03.2011
comment
О, это потому, что getValueAt(r,i) возвращает Object.. Но я все еще не могу сделать это при использовании AbstractTableModel. Только методом проб и ошибок.. Может ли кто-нибудь объяснить мне с помощью AbstractTableModel? - person bsm; 22.03.2011
comment
Почему бы вместо этого не использовать DefaultTableModel? - person Hovercraft Full Of Eels; 22.03.2011

Вот как вы можете создать «перечеркнутый шрифт»:

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

Одним из способов применения шрифта является использование рендеринга строк таблицы подход. Взгляните на пример цвета фона. Вместо установки фона рендерера вы можете установить Font.

В противном случае вам нужно будет создать собственный рендерер для столбцов в вашей таблице, чтобы использовать соответствующий шрифт.

person camickr    schedule 11.03.2011

Добавьте прослушиватель к флажку, который будет добавлять/удалять метку. Вот пример коробки и этикетки, которые могут быть полезны:

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);
  }
}
person Vladp    schedule 11.03.2011