GridLayout Live-Demo
Die GridLayout-Live-Demo erleichtert spielerisch durch Erkunden und Verändern von Werten in der Benutzeroberfläche das Verständnis von GridLayout.
Diese Demo enthält u.a. auch ein Beispiel, wie ein JSpinner
verwendet werden kann und wie man einfache Icons selbst zeichnet.
Kopieren Sie sich die Quellcodes in einzelne Java-Dateien. Achten Sie auf die richtige Verteilung der Klassen in die im Code angegebenen Packages, oder kommentieren Sie die Package-Anweisung einfach aus, wenn Sie unsicher sind. Anschließend kompilieren Sie die Java-Dateien und starten die Hauptklasse.
Inhaltsverzeichnis
- 1 GridLayoutDemo.java - Die Hauptklasse
- 2 Klassen aus dem event-Package
- 2.1 Interface GridOperations - die Funktionen der Demo
- 2.2 AddAction - Hinzufügen neuer Komponenten
- 2.3 RemoveAction - Entfernen von Komponenten
- 2.4 HgapChangeAction - Horizontalen Abstand einstellen
- 2.5 VgapChangeAction - Vertikalen Abstand einstellen
- 2.6 RowCountChangeAction - Anzahl der Zeilen im Gitter einstellen
- 2.7 ColumnCountChangeAction - Anzahl der Spalten im Gitter einstellen
- 3 Icons
- 4 Fragen
- 5 Weiterführende Links
GridLayoutDemo.java - Die Hauptklasse
/*
* GridLayout-Live-Demo
*
* Copyright (c) 2019 Gernot Segieth - wiki.byte-welt.net
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package gridlayout;
import gridlayout.event.AddAction;
import gridlayout.event.ColumnCountChangeAction;
import gridlayout.event.GridOperations;
import gridlayout.event.HgapChangeAction;
import gridlayout.event.RemoveAction;
import gridlayout.event.RowCountChangeAction;
import gridlayout.event.VgapChangeAction;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
/**
* Die GridLayout-Live-Demo erleichtert spielerisch durch Erkunden und Verändern
* von Werten in der Benutzeroberfläche das Verständnis von GridLayout.
*
* @author Gernot Segieth, (c)2019
* @see java.awt.GridLayout
*/
public class GridLayoutDemo implements GridOperations {
private JPanel gridPanel;
private GridLayout layout;
private SpinnerNumberModel hgapModel; //JSpinner zur Eingabe horizontaler Abstände
private SpinnerNumberModel vgapModel; //JSpinner zur Eingabe vertikaler Abstände
private SpinnerNumberModel rowModel; //JSpinner zur Eingabe der Zeilen im Gitter
private SpinnerNumberModel colModel; //JSpinner zur Eingabe der Spalten im Gitter
private int compCount; //zählt die Komponenten
public GridLayoutDemo() {
JFrame frame = new JFrame("GridLayout (Live-Demo)");
frame.add(createGridPanel(), BorderLayout.CENTER);
frame.add(createControlPanel(), BorderLayout.NORTH);
frame.add(createSouthPanel(), BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
@Override
public void addComponent() {
gridPanel.add(new JButton(String.valueOf(++compCount)));
gridPanel.validate();
gridPanel.repaint();
}
@Override
public void removeComponent() {
if (compCount > 0) {
gridPanel.remove(--compCount);
gridPanel.validate();
gridPanel.repaint();
}
}
@Override
public void changeHgap() {
layout.setHgap((int) hgapModel.getNumber());
update();
}
@Override
public void changeVgap() {
layout.setVgap((int) vgapModel.getNumber());
update();
}
@Override
public void changeRowCount() {
layout.setRows((int) rowModel.getNumber());
update();
}
@Override
public void changeColumnCount() {
layout.setColumns((int) colModel.getNumber());
update();
}
private JPanel createGridPanel() {
layout = new GridLayout();
gridPanel = new JPanel(layout) {
@Override
public Dimension getPreferredSize() {
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
return new Dimension(size.width * 40 / 100, size.height * 40 / 100);
}
};
gridPanel.setBackground(Color.WHITE);
return gridPanel;
}
private JPanel createControlPanel() {
JButton addButton = new JButton(new AddAction(this));
JButton removeButton = new JButton(new RemoveAction(this));
hgapModel = new SpinnerNumberModel(layout.getHgap(), 0, 50, 1);
JSpinner hgapSpinner = new JSpinner(hgapModel);
hgapSpinner.addChangeListener(new HgapChangeAction(this));
vgapModel = new SpinnerNumberModel(layout.getVgap(), 0, 50, 1);
JSpinner vgapSpinner = new JSpinner(vgapModel);
vgapSpinner.addChangeListener(new VgapChangeAction(this));
rowModel = new SpinnerNumberModel(layout.getRows(), 0, 10, 1);
JSpinner rowSpinner = new JSpinner(rowModel);
rowSpinner.addChangeListener(new RowCountChangeAction(this));
colModel = new SpinnerNumberModel(layout.getColumns(), 0, 10, 1);
JSpinner columnSpinner = new JSpinner(colModel);
columnSpinner.addChangeListener(new ColumnCountChangeAction(this));
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
GridBagConstraints gbc = new GridBagConstraints();
int space = 20;
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(new JLabel("setRows( "), gbc);
gbc.gridx++;
panel.add(rowSpinner, gbc);
gbc.insets = new Insets(0, 0, 0, space);
gbc.gridx++;
panel.add(new JLabel(" );"), gbc);
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridx++;
panel.add(new JLabel("setColumns( "), gbc);
gbc.gridx++;
panel.add(columnSpinner, gbc);
gbc.insets = new Insets(0, 0, 0, space);
gbc.gridx++;
panel.add(new JLabel(" );"), gbc);
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridx++;
panel.add(new JLabel("setHgap( "), gbc);
gbc.gridx++;
panel.add(hgapSpinner, gbc);
gbc.insets = new Insets(0, 0, 0, space);
gbc.gridx++;
panel.add(new JLabel(" );"), gbc);
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridx++;
panel.add(new JLabel("setVgap( "), gbc);
gbc.gridx++;
panel.add(vgapSpinner, gbc);
gbc.insets = new Insets(0, 0, 0, space);
gbc.gridx++;
panel.add(new JLabel(" );"), gbc);
panel.add(addButton);
panel.add(removeButton);
return panel;
}
private JPanel createSouthPanel() {
JLabel label = new JLabel("<html>©2019 Gernot Segieth, Byte-Welt-Wiki (https://wiki.byte-welt.net)</html>");
label.setForeground(label.getBackground().darker());
label.setFont(label.getFont().deriveFont(10f));
JPanel panel = new JPanel();
panel.add(label);
return panel;
}
private void update() {
SwingUtilities.invokeLater(() -> {
gridPanel.updateUI();
});
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
//UIManager.put("swing.boldMetal", false);
SwingUtilities.invokeLater(() -> {
new GridLayoutDemo();
});
}
}
Klassen aus dem event-Package
Die im Folgenden aufgelisteten Quellcodes dienen der Reaktion auf Maus gesteuerte Ereignisse an der Benutzeroberfläche. Komponenten, die für sie bestimmte Aktionen erkennen, leiten die Informationen an die verarbeitenden Listener weiter. Diese wiederum sorgen dafür, dass Methoden als Reaktion auf die Manipulation der Benutzeroberfläche aufgerufen werden, die die Benutzeroberfläche entsprechend anpassen.
Interface GridOperations - die Funktionen der Demo
package gridlayout.event;
/**
*
* @author Gernot Segieth
*/
public interface GridOperations {
public void addComponent();
public void removeComponent();
public void changeHgap();
public void changeVgap();
public void changeRowCount();
public void changeColumnCount();
}
AddAction - Hinzufügen neuer Komponenten
package gridlayout.event;
import gridlayout.icons.MoreIcon;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
/**
*
* @author Gernot Segieth
*/
public class AddAction extends AbstractAction {
private final GridOperations go;
public AddAction(GridOperations go) {
super("", new MoreIcon());
this.go = go;
}
@Override
public void actionPerformed(ActionEvent ae) {
go.addComponent();
}
}
RemoveAction - Entfernen von Komponenten
package gridlayout.event;
import gridlayout.icons.LessIcon;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
/**
*
* @author Gernot Segieth
*/
public class RemoveAction extends AbstractAction {
private final GridOperations go;
public RemoveAction(GridOperations go) {
super("", new LessIcon());
this.go = go;
}
@Override
public void actionPerformed(ActionEvent ae) {
go.removeComponent();
}
}
HgapChangeAction - Horizontalen Abstand einstellen
package gridlayout.event;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
* @author Gernot Segieth
*/
public class HgapChangeAction implements ChangeListener {
private final GridOperations go;
public HgapChangeAction(GridOperations go) {
this.go = go;
}
@Override
public void stateChanged(ChangeEvent ce) {
go.changeHgap();
}
}
VgapChangeAction - Vertikalen Abstand einstellen
package gridlayout.event;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
* @author Gernot Segieth
*/
public class VgapChangeAction implements ChangeListener {
private final GridOperations go;
public VgapChangeAction(GridOperations go) {
this.go = go;
}
@Override
public void stateChanged(ChangeEvent ce) {
go.changeVgap();
}
}
RowCountChangeAction - Anzahl der Zeilen im Gitter einstellen
package gridlayout.event;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
* @author Gernot Segieth
*/
public class RowCountChangeAction implements ChangeListener {
private final GridOperations go;
public RowCountChangeAction(GridOperations go) {
this.go = go;
}
@Override
public void stateChanged(ChangeEvent ce) {
go.changeRowCount();
}
}
ColumnCountChangeAction - Anzahl der Spalten im Gitter einstellen
package gridlayout.event;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
* @author Gernot Segieth
*/
public class ColumnCountChangeAction implements ChangeListener {
private final GridOperations go;
public ColumnCountChangeAction(GridOperations go) {
this.go = go;
}
@Override
public void stateChanged(ChangeEvent ce) {
go.changeColumnCount();
}
}
Icons
Fehlen nur noch die Icons, die auch als Java-Klasse angelegt werden können.
Dieses Codestück zeigt, wie man ein einfaches Icon selbst zeichnet. Hier zeichnen wir ein Minus-Symbol in den JButton.
Zunächst das Minus-Icon:
package gridlayout.icons;
import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import javax.swing.Icon;
public class LessIcon implements Icon {
@Override
public void paintIcon(Component c, Graphics gr, int x, int y) {
Graphics2D g = (Graphics2D) gr;
AffineTransform at = new AffineTransform();
at.translate(x, y);
at.scale(getIconWidth(), getIconHeight());
Shape transformedShape = at.createTransformedShape(createShape());
g.setStroke(new BasicStroke(2));
g.draw(transformedShape);
g.dispose();
}
@Override
public int getIconWidth() {
return 15;
}
@Override
public int getIconHeight() {
return getIconWidth();
}
private Shape createShape() {
Path2D path = new GeneralPath();
path.moveTo(0.1f, 0.5f);
path.lineTo(0.9f, 0.5f);
return path;
}
}
Dieses Codestück zeigt, wie man ein einfaches Icon selbst zeichnet. Hier zeichnen wir ein Plus-Symbol in den JButton.
Das Plus-Icon:
package gridlayout.icons;
import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import javax.swing.Icon;
public class MoreIcon implements Icon {
@Override
public void paintIcon(Component c, Graphics gr, int x, int y) {
Graphics2D g = (Graphics2D) gr;
AffineTransform at = new AffineTransform();
at.translate(x, y);
at.scale(getIconWidth(), getIconHeight());
Shape transformedShape = at.createTransformedShape(createShape());
g.setStroke(new BasicStroke(2));
g.draw(transformedShape);
g.dispose();
}
@Override
public int getIconWidth() {
return 15;
}
@Override
public int getIconHeight() {
return getIconWidth();
}
private Shape createShape() {
Path2D path = new GeneralPath();
path.moveTo(0.5f, 0.1f);
path.lineTo(0.5f, 0.9f);
path.moveTo(0.1f, 0.5f);
path.lineTo(0.9f, 0.5f);
return path;
}
}
Fragen
Das Thema wurde nicht ausreichend behandelt? Du hast Fragen dazu und brauchst weitere Informationen? Lass Dir von uns helfen!
- Besuche uns im Byte-Welt-Forum
- Besuche unseren Chat
Wir helfen dir gerne!
Dir hat dieser Artikel gefallen? Oder Du hast Fehler entdeckt und möchtest zur Berichtigung beitragen? Prima! Schreibe einen Kommentar!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Weiterführende Links
- Mehr zum GridLayout und anderen LayoutManagern
- JSpinner mit Zahl und Einheit