# JButton mit JLabel verdecken?



## Jens81 (29. Jan 2010)

Hallo zusammen,

ist es möglich, einen Teil eines JButtons z.B. durch ein JLabel zu überdecken? Ich habe mal ein einfaches Testprogramm geschrieben, allerdings funktioniert es so nicht (das JLabel scheint immer unter dem JButton zu liegen). Der Button soll im nicht-sichtbaren Bereich (wenn es denn funktionieren würde) auch nicht aktivierbar sein. 


```
public static void main(String[] args) {
		JFrame test = new JFrame();
		test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		test.setLayout(null);
		test.setResizable(false);
		test.setSize(300,400);
		
		JButton but = new JButton("Drück mich!");
		but.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("Knopf gedrückt!");
			}
		});
		but.setBounds(60,160,160,40);
		test.add(but);
		
		JLabel abdeckung = new JLabel();
		abdeckung.setOpaque(true);
		abdeckung.setBackground(Color.BLACK);
		abdeckung.setBounds(70,120,100,100);
		test.add(abdeckung);	
		
		test.setVisible(true);
	}
```


----------



## Michael... (29. Jan 2010)

Nur mal so aus Neugierde:
Wozu soll das gut sein? Bzw. erläutere Mal was Du vorhast, da gibt's bestimmt ein besseres Vorgehen.


----------



## Tomate_Salat (29. Jan 2010)

hmm dachte man könnte es mit [c]setComponentZOrder(comp, index);[/c] lösen, aber da füllt entweder das Label oder der Button alles aus (hab dann iwo gelesen, dass das eher für layerdPanes gedacht ist). Aber wofür brauchst du das?! Wenn der Button inaktiv oder nicht sichtbar sein soll, dann löse dass doch einfach mit [c]setVisible(false);[/c] oder [c]setEnabled(false);[/c]

Mit freundlichen Grüßen

Tomate_Salat


----------



## Jens81 (29. Jan 2010)

Mit setComponentZOrder hatte ich es auch probiert, bin aber auch auf die von dir geschilderten Probleme gestoßen.

Ich will den Button ja nicht deaktivieren oder unsichtbar machen, sondern nur eine Ecke überdecken. Von daher helfen mir setVisible und setEnabled nicht.


Hintergrund: Ich habe eine JTable mit boolean-Werten (JCheckBoxen), die folgende Form haben muss:


```
S1  S2  S3
Z1            |
Z2      ______|
Z3 ___|
```

Daher dachte ich mir, ich könnte den rechten, unteren Teil einfach mit nem JLabel verdecken. Nicht besondern schön, aber schnell & einfach (zumindest in der Theorie  )

Der Einfachheit halber daher das Beispiel mit dem JButton. Aber das scheint ja aufwendiger zu sein als gedacht...


----------



## eRaaaa (29. Jan 2010)

mit nem GlassPane könnte man da sicherlich was machen, zumindestens das überdecken ließe sich irgendwie hinbekommen

```
JFrame f = new JFrame();
	JButton button = new JButton("Drück mich!");
	JPanel p = new JPanel();
	p.add(button);
	f.getContentPane().add(p);
	final JPanel glass = (JPanel) f.getGlassPane();
	glass.setVisible(true);
	glass.add(new JLabel("LABEL"));
	f.pack();
	f.setVisible(true);
	f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
```

vllt hilft dir das schon weiter bei google was in diese richtung zu finden..(ich bin der meinung, hier irgendwo hatte auch schon mal jmd sowas vor gehabt)


----------



## Michael... (29. Jan 2010)

Jens81 hat gesagt.:


> Hintergrund: Ich habe eine JTable mit boolean-Werten (JCheckBoxen), die folgende Form haben muss:
> 
> 
> ```
> ...



Muss es denn tatsächlich eine JTable sein oder geht es nur um die "tabellarische" Anordnung?


----------



## Jens81 (29. Jan 2010)

Es muss schon die JTable sein. Mir würds ja auch langen die Ecke via TableCellRenderer grau darzustellen, habe aber das Problem, dass ich nicht weiß, wie man die JCheckBoxen "verstecken" könnte. Im TableModel sind diese ja nur für ganze Spalten zu definieren.. daher die JLabel-Idee

Edit: Die Zellen einzeln grau darzustellen funktioniert nun so, dass auch die JCheckBoxen verdeckt sind. Allerdings wäre ein großes Label, welches die gesamte Ecke überdeckt, optisch ansprechender


----------



## Michael... (29. Jan 2010)

Vielleicht reicht ja sowas in der Art aus:

```
import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class CheckTableRenderer extends JFrame {
	private JTable table;
	
	public CheckTableRenderer () {
		DefaultTableModel model = new DefaultTableModel(
				new Object[][] {{true, false, true}, {true, true, true}, {true, null, null}}, 
				new String[] {"S1", "S2", "S3"}); 
		table = new JTable(model) {
			public Class<?> getColumnClass(int column) {
				return Boolean.class;
			}
			
			public boolean isCellEditable(int row, int column) {
				return getValueAt(row, column)!=null;
			}
			
			public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
				if (getValueAt(row, column)==null)
					return null;
				return super.prepareRenderer(renderer, row, column);
			}
		};
		this.getContentPane().add(new JScrollPane(table));
	}
	
	public static void main(String[] args) {
		JFrame frame = new CheckTableRenderer();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
```


----------



## Jens81 (29. Jan 2010)

Hatte wohl zeitgleich meinen Beitrag editiert 

Danke (trotzdem) für den Vorschlag. Meine Lösung sieht ähnlich aus, bzw. läuft auf das gleiche Ergebnis heraus. Der Vorteil eines überdeckenden Labels wäre, dass die Gitternetzlinien auch überdeckt wären.

So lange mir oder euch nichts "besseres" einfällt, muss das erstmal so reichen...


----------



## Firestorm87 (31. Jan 2010)

Hab da was nettes in nem Oreily-Buch gefunden:

```
package de.tobiaskahl.neuesprojekt.client;

// OverlayTest.java
// A test of the OverlayLayout manger . . .
//
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.OverlayLayout;

public class OverlayTest extends JFrame {
	public class BasicWindowMonitor extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			Window w = e.getWindow();
			w.setVisible(false);
			w.dispose();
			System.exit(0);
		}
	}

	public class GridPanel extends JPanel {
		@Override
		public void paint(Graphics g) {
			super.paint(g);
			int w = this.getSize().width;
			int h = this.getSize().height;
			System.out.println("w: " + w + " h: " + h);
			g.setColor(Color.red);
			g.drawRect(0, 0, w - 1, h - 1);
			g.drawLine(w / 2, 0, w / 2, h);
			g.drawLine(0, h / 2, w, h / 2);
		}
	}

	public class SimpleReporter implements ActionListener {
		public void actionPerformed(ActionEvent ae) {
			System.out.println(ae.getActionCommand());
		}
	}

	public static void main(String args[]) {
		float alignments[] = { 0.0f, 0.0f, 0.0f, 0.0f };
		if (args.length == 4) {
			for (int i = 0; i < 4; i++) {
				alignments[i] = Float.valueOf(args[i]).floatValue();
			}
		}
		OverlayTest ot = new OverlayTest(alignments);
		ot.setSize(500, 300);
		ot.setVisible(true);
	}

	/**
	 * @param alignments
	 */
	public OverlayTest(float[] alignments) {
		super("OverlayLayout Test");
		this.setSize(400, 200);
		this.addWindowListener(new BasicWindowMonitor());
		Container c = this.getContentPane();
		final JPanel p1 = new GridPanel();
		final OverlayLayout overlay = new OverlayLayout(p1);
		p1.setLayout(overlay);
		final JButton jb1 = new JButton("B1");
		final JButton jb2 = new JButton("Button 2");
		final JButton jb3 = new JButton("Another Button");
		SimpleReporter reporter = new SimpleReporter();
		jb1.addActionListener(reporter);
		jb2.addActionListener(reporter);
		jb3.addActionListener(reporter);
		p1.add(jb1);
		p1.add(jb2);
		p1.add(jb3);
		JPanel p2 = new JPanel();
		p2.setLayout(new GridLayout(1, 7));
		final JTextField x1 = new JTextField("0", 4); // Button1 x alignment
		final JTextField y1 = new JTextField("0", 4); // Button1 y alignment
		final JTextField x2 = new JTextField("0", 4);
		final JTextField y2 = new JTextField("0", 4);
		final JTextField x3 = new JTextField("0", 4);
		final JTextField y3 = new JTextField("0", 4);
		p2.add(x1);
		p2.add(y1);
		p2.add(x2);
		p2.add(y2);
		p2.add(x3);
		p2.add(y3);
		JButton updateButton = new JButton("Update");
		// Note that we expect real values in the text fields
		updateButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				jb1.setAlignmentX(Float.valueOf(x1.getText().trim()).floatValue());
				jb1.setAlignmentY(Float.valueOf(y1.getText().trim()).floatValue());
				jb2.setAlignmentX(Float.valueOf(x2.getText().trim()).floatValue());
				jb2.setAlignmentY(Float.valueOf(y2.getText().trim()).floatValue());
				jb3.setAlignmentX(Float.valueOf(x3.getText().trim()).floatValue());
				jb3.setAlignmentY(Float.valueOf(y3.getText().trim()).floatValue());
				overlay.invalidateLayout(p1);
				p1.doLayout();
			}
		});
		p2.add(updateButton);
		c.add(p1, BorderLayout.CENTER);
		c.add(p2, BorderLayout.SOUTH);
	}
}
```


----------

