Swing JTable - selectionBackground transparent

martin82

Mitglied
Hi,

ich verwende swingX und möchte die Selektierung meiner Tabelle transparent machen, d.h. wenn eine Zeile(oder Zelle) bereits mit einer Farbe eingefärbt ist und die Zeile selektiert wird, dass immer noch ersichtlich bleibt in welcher Farbe die Zeile bzw. Zelle eingefärbt ist.

Ich konnte es bereits teilweise mittels eines Renderers lösen:

Java:
public class MyTableCellRenderer extends DefaultTableCellRenderer {

      public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int view_row, int col) {

                // call super-method to set this
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, view_row, col);

                // set background properly
                if (isSelected) {
                        this.setBackground(table.getSelectionBackground());   
                        paint = Form.getDarkerColor((Color)paint, 0.15);
                }
                else
                        this.setBackground(table.getBackground());


 }

 public void paint(Graphics arg0) {
               
                if (paint != null){
                        Graphics2D g = (Graphics2D)arg0;
                        g.setPaint(paint);
                        g.fillRect(0, 0, this.getWidth(), this.getHeight());
                }
                super.paint(arg0);
        }

}


In meinem Formular hab ich dann noch setSelectionBackground(null) gesetzt und nachdem die Tabelle gefüllt wurde setze ich die erste Zeile als selektiert.

Allerdings hab ich jetzt sporadisch das Problem, dass die Selektierung der ersten Zeile nicht eingefärbt wird. Wenn ich mit der Maus rollover über die erste Zeile gehe, wird die Selektierung gezeichnet. Fehlt mir irgendwo ein repaint()?
 
Vielen Dank für den Hinweis. Ich werd es mal probieren umzuschreiben. Mein Renderer stammt noch aus dem Jahre 2006. Seit wann wird das anders empfohlen?
In welchen Fällen sollte man eigentlich immer noch einen eigenen Renderer schreiben anstatt die Variante mit prepareRenderer?
 
Hier mal ein Bsp. mit zwei Varianten, wobei ich die Variante in der ersten Spalte eher unschön finde, da der Zellentext ebenfalls von der transparenten Farbe überlagert ist.
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class TableAlphaSelectionDemo extends JFrame {
	private JTable table;
	
	public TableAlphaSelectionDemo() {
		table = new JTable(new Object[][] {{"0xFF0000", "0xFF0000"}, {"0x00FF00", "0x00FF00"}, {"0x0000FF", "0x0000FF"}}, new String[] {"Variante1", "Variante2"});
		table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
			private boolean isSelected;
			public Component getTableCellRendererComponent(JTable table, Object value,
                    boolean isSelected, boolean hasFocus, int row, int column) {
				super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				this.setBackground(Color.decode(value.toString()));
				this.isSelected = isSelected;
				return this;
			}
			
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				if (!this.isSelected)
					return;
				Color color = table.getSelectionBackground();
				g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 100));
				g.fillRect(0, 0, this.getWidth(), this.getHeight());
			}
		});
		table.getColumnModel().getColumn(1).setCellRenderer(new MyCellRenderer());
		this.getContentPane().add(new JScrollPane(table));
		table.getSelectionModel().setSelectionInterval(0, 0);
	}
	
	class MyCellRenderer extends DefaultTableCellRenderer {
		private boolean isSelected;
		private JPanel panel;
		
		public MyCellRenderer() {
			this.setOpaque(false);
			panel = new JPanel(new BorderLayout()) {
				public void paintComponent(Graphics g) {
					super.paintComponent(g);
					if (!isSelected)
						return;
					Color color = table.getSelectionBackground();
					g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 100));
					g.fillRect(0, 0, this.getWidth(), this.getHeight());
				}
			};
			panel.add(this, BorderLayout.CENTER);
		}
		
		public Component getTableCellRendererComponent(JTable table, Object value,
				boolean isSelected, boolean hasFocus, int row, int column) {
			Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
			this.isSelected = isSelected;
			panel.setBackground(Color.decode(value.toString()));
			return panel;
		}
	}
	
	public static void main(String[] args) {
		JFrame frame = new TableAlphaSelectionDemo();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 
Ist alles nur eine Frage des Renderers:
Java:
class MyCellRenderer extends DefaultTableCellRenderer {
	private boolean isSelected;
	private JPanel panel;
	private Color baseColor;
	
	public MyCellRenderer() {
		this.setOpaque(false);
		baseColor = Color.WHITE;
		panel = new JPanel(new BorderLayout()) {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				Graphics2D g2 = (Graphics2D)g;
				GradientPaint gp = new GradientPaint(0, 0, baseColor, this.getWidth(), this.getHeight(), Color.WHITE);
				g2.setPaint(gp);
				g2.fillRect(0, 0, this.getWidth(), this.getHeight());
				if (!isSelected)
					return;
				Color color = table.getSelectionBackground();
				g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 100));
				g.fillRect(0, 0, this.getWidth(), this.getHeight());
			}
		};
		panel.add(this, BorderLayout.CENTER);
	}
		
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {
		Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
		this.isSelected = isSelected;
		//panel.setBackground(Color.decode(value.toString()));
		baseColor = Color.decode(value.toString());
		return panel;
	}
}
 

Zurück
Oben