2017-09-24 3 views
1

Si j'utilise les éléments suivants pour afficher une JTable:Ajouter un comportement à une cellule par défaut JTable renderer

package jtable.fontsize; 
import java.awt.BorderLayout; 
import java.awt.Font; 
import java.lang.reflect.InvocationTargetException; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 

import rcutil.swing.table.LastColumnChangesWidthJTable; 


public class JTableCellPlay extends JFrame 
{ 
    public JTableCellPlay() 
    { 
    super("setting Table font size"); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    } 

    public static void main(String ... arguments) throws InvocationTargetException, InterruptedException 
    { 
    JTableCellPlay mainScreen = new JTableCellPlay(); 
    mainScreen.go(); 
    } 

    public void go() throws InvocationTargetException, InterruptedException 
    { 
    SwingUtilities.invokeAndWait(new Runnable() { public void run() { createScreen(); } }); 
    setVisible(true); 
    } 

    public void createScreen() 
    { 
    LastColumnChangesWidthJTable aLittleJTable = new LastColumnChangesWidthJTable(new LittleTableModel()); 
    aLittleJTable.setDefaultRenderer(Integer.class, new IntegerCellRenderer()); 
    JScrollPane scrollPane = new JScrollPane(aLittleJTable); 
    add(scrollPane, BorderLayout.CENTER); 
    pack(); 
    } 
} 

avec le moteur de rendu suivant:

package jtable.fontsize; 

import java.awt.Color; 
import java.awt.Component; 

import javax.swing.JLabel; 
import javax.swing.JTable; 
import javax.swing.table.TableCellRenderer; 


public class IntegerCellRenderer extends JLabel implements TableCellRenderer 
{ 
    @Override 
    public Component getTableCellRendererComponent 
         (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
    { 
    String resultString = String.format("~%d~", (Integer)value); 
    setText(resultString); 
    setHorizontalAlignment(JLabel.CENTER); 
// if (isSelected) 
// { 
//  setOpaque(true); // evidently necessary for JLabel as a component in a JTable cell 
//  setBackground(Color.GRAY); 
// } 
    return this; 
    } 
} 

et le modèle suivant (afin que votre code courir, oui, je sais qu'il ya d'autres façons de le faire cette partie):

package jtable.fontsize; 

import javax.swing.table.AbstractTableModel; 

public class LittleTableModel extends AbstractTableModel 
{ 
    public Class<? extends Object> getColumnClass(int column) 
    { 
    Class<? extends Object> c = null; 
    switch (column) 
    { 
    case 0: c = String.class; break; 
    case 1: c = Integer.class; break; 
    case 2: c = String.class; break; 
    } 
    return c; 
    } 

    String[] columnNames = { "first", "second", "third" }; 
    Object[][] data = { { "one", 2, "three" }, { "four", 5, "six" } }; 

    public int getColumnCount() { return 3; } 
    public int getRowCount() { return 2; } 
    public String getColumnName(int index) { return columnNames[index]; } 

    public Object getValueAt(int row, int column) 
    { 
    Object result = data[row][column]; 
    return result; 
    } 
} 

Puis, quand je sélectionne une des lignes, les deux Str Les colonnes ing obtiennent une sélection en surbrillance, mais pas la colonne "Entier".

Si je commente la ligne qui définit le moteur de rendu "Integer", cliquer sur une ligne sélectionne la ligne entière comme prévu. Je sais que je peux utiliser les lignes commentées dans le moteur de rendu pour surligner la cellule, en ajoutant setOpaque(true) et setBackground(Color) et même jouer à des jeux pour obtenir les couleurs de fond sélectionnées et non sélectionnées, mais je soupçonne qu'il y a un moyen de utilisez le même moteur de rendu que celui utilisé à l'origine pour des choses comme ça, et utilisez simplement le code dans mon moteur de rendu pour faire les choses spéciales dont j'ai besoin. Quelqu'un peut-il expliquer comment cela fonctionne?

+0

Plusieurs approches sont proposées dans [* cellule surligné lorsque la ligne est sélectionnée *] (https://stackoverflow.com/q/32301649/230513). – trashgod

Répondre

1

Pourquoi ne pas simplement donner à votre moteur de rendu un bloc où vous annulez les modifications effectuées dans le bloc if?

if (isSelected) { 
    setOpaque(true); 
    setBackground(Color.GRAY); 
} else { 
    setOpaque(false); // allow underlying color to show 
    setBackground(null); // no color added 
} 

Ou une autre option est d'avoir votre classe renderer étendre DefaultTableCellRenderer plutôt que de mettre en œuvre TableCellRenderer, vous permettant d'utiliser les capacités mettant en évidence innées du moteur de rendu par défaut:

@SuppressWarnings("serial") 
class IntegerCellRenderer2 extends DefaultTableCellRenderer { 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 
      int row, int column) { 
     String resultString = String.format("~%d~", (Integer) value); 
     setText(resultString); 
     setHorizontalAlignment(JLabel.CENTER); 
     return super.getTableCellRendererComponent(table, resultString, isSelected, hasFocus, row, column); 
    } 
} 

Notez que vous pouvez définir des propriétés du moteur de rendu dans son constructeur. Par exemple:

@SuppressWarnings("serial") 
class IntegerCellRenderer2 extends DefaultTableCellRenderer { 
    public IntegerCellRenderer2() { 
     setHorizontalAlignment(JLabel.CENTER); 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 
      int row, int column) { 
     String resultString = String.format("~%d~", (Integer) value); 
     setText(resultString); 
     // setHorizontalAlignment(JLabel.CENTER); 
     return super.getTableCellRendererComponent(table, resultString, isSelected, hasFocus, row, column); 
    } 
} 
+0

Eh bien, je ne sais pas quel est le réglage opaque et le fond, a priori, pas plus que je sais que la couleur de sélection est grise. Et comme je l'ai dit, je sais que je peux faire des appels pour savoir ce que c'est, mais je voulais savoir une meilleure façon. Votre deuxième méthode semble fonctionner, même si cela me semble douteux - et si le rendu par défaut définissait l'alignement? Je n'aime pas avoir de code dans ma classe qui dépend des internes de sa superclasse. – arcy

+0

@arcy: qu'est-ce que * exactement * essayez-vous de faire? –

+0

@arcy; Si vous utilisez le rendu par défaut, vous pouvez interroger le composant du super quant à son état d'arrière-plan et son état de propriété opaque assez facilement, mais encore une fois, qu'est-ce que vous essayez de faire avec cela? –