JComponentBounds: Unterschied zwischen den Versionen
Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springenK |
|||
(18 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | Die Klasse | + | __TOC__ |
− | < | + | =Die Klasse und ein Anwendungsbeispiel= |
+ | ==JComponentBounds== | ||
+ | Die Klasse <code>JComponentBounds</code> erlaubt es, {{JAPI|JComponent}}s zu verschieben und in der Grösse zu verändern. Die Klasse "PictureDemo" weiter unten zeigt ein Anwendungsbeispiel. | ||
+ | <syntaxhighlight lang="java"> | ||
/* | /* | ||
* JComponentBounds.java | * JComponentBounds.java | ||
− | * | + | * |
− | * This class aims at making | + | * This class aims at making any JComponent resizable |
− | * | + | * simply by putting it inside a JInternalFrame. |
+ | * The wrapped JComponent is made moveable | ||
+ | * by means of a MouseInputAdapter. | ||
+ | * The class includes a "snap to grid" option. | ||
+ | * | ||
* author: Andre Uhres | * author: Andre Uhres | ||
− | * | + | * update April 15, 2010 at 6:00 |
+ | * update December 21, 2010 at 15:00 | ||
*/ | */ | ||
Zeile 18: | Zeile 26: | ||
public class JComponentBounds extends JInternalFrame { | public class JComponentBounds extends JInternalFrame { | ||
+ | public static final int FOCUS_GAINED = 97531; | ||
private JComponent componentsContainer; | private JComponent componentsContainer; | ||
private boolean focused; | private boolean focused; | ||
− | |||
− | |||
private JComponent comp; | private JComponent comp; | ||
private static final Color TRANSPARENT = new Color(0.0f, 0.0f, 0.0f, 0.0f); | private static final Color TRANSPARENT = new Color(0.0f, 0.0f, 0.0f, 0.0f); | ||
Zeile 42: | Zeile 49: | ||
} | } | ||
− | public JComponentBounds(final JComponent comp, final int x, final int y, final boolean focused) { | + | public JComponentBounds(final JComponent comp, final int x, final int y, |
+ | final boolean focused) { | ||
super(); | super(); | ||
this.comp = comp; | this.comp = comp; | ||
this.focused = focused; | this.focused = focused; | ||
− | setBounds(x, y, comp.getPreferredSize().width, comp.getPreferredSize().height); | + | setBounds(x, y, |
+ | comp.getPreferredSize().width, comp.getPreferredSize().height); | ||
setResizable(true); | setResizable(true); | ||
setVisible(true); | setVisible(true); | ||
Zeile 52: | Zeile 61: | ||
setBackground(TRANSPARENT); | setBackground(TRANSPARENT); | ||
((BasicInternalFrameUI) getUI()).setNorthPane(null); | ((BasicInternalFrameUI) getUI()).setNorthPane(null); | ||
− | setBorder(BorderFactory.createEmptyBorder(MARGIN, MARGIN, MARGIN, MARGIN)); | + | setBorder(BorderFactory.createEmptyBorder( |
+ | MARGIN, MARGIN, MARGIN, MARGIN)); | ||
comp.setFocusable(true); | comp.setFocusable(true); | ||
add(comp); | add(comp); | ||
ml = new MouseInputAdapter() { | ml = new MouseInputAdapter() { | ||
+ | |||
+ | private Point p1; | ||
@Override | @Override | ||
public void mousePressed(final MouseEvent e) { | public void mousePressed(final MouseEvent e) { | ||
+ | p1 = e.getPoint(); | ||
componentsContainer = (JComponent) getParent(); | componentsContainer = (JComponent) getParent(); | ||
− | |||
− | |||
e.setSource(JComponentBounds.this); | e.setSource(JComponentBounds.this); | ||
− | //componentsContainer might use the event | + | //componentsContainer might use the mousePressed event |
//to take hidden components to the top: | //to take hidden components to the top: | ||
componentsContainer.dispatchEvent(e); | componentsContainer.dispatchEvent(e); | ||
Zeile 72: | Zeile 83: | ||
componentsContainer = (JComponent) getParent(); | componentsContainer = (JComponent) getParent(); | ||
e.setSource(JComponentBounds.this); | e.setSource(JComponentBounds.this); | ||
− | //componentsContainer might use the event | + | //componentsContainer might use the mouseReleased event |
//to take hidden components to the top: | //to take hidden components to the top: | ||
componentsContainer.dispatchEvent(e); | componentsContainer.dispatchEvent(e); | ||
Zeile 82: | Zeile 93: | ||
return; | return; | ||
} | } | ||
+ | //drag operation: | ||
+ | Point p2 = e.getPoint(); | ||
+ | Point loc = getLocation(); | ||
+ | loc.translate(p2.x - p1.x, p2.y - p1.y); | ||
+ | setLocation(loc); | ||
componentsContainer = (JComponent) getParent(); | componentsContainer = (JComponent) getParent(); | ||
− | componentsContainer. | + | //auto scroll: |
− | + | componentsContainer.scrollRectToVisible( | |
− | + | new Rectangle(loc.x, loc.y, getWidth(), getHeight())); | |
− | componentsContainer. | + | //componentsContainer might use the focusGained event |
− | + | //to keep the dragged component in front: | |
+ | FocusListener[] focusListeners = componentsContainer.getFocusListeners(); | ||
+ | if (focusListeners != null && focusListeners.length > 0) { | ||
+ | FocusListener fl = focusListeners[0]; | ||
+ | fl.focusGained( | ||
+ | new FocusEvent(JComponentBounds.this, | ||
+ | JComponentBounds.FOCUS_GAINED)); | ||
+ | } | ||
} | } | ||
}; | }; | ||
Zeile 95: | Zeile 118: | ||
public void keyPressed(final KeyEvent e) { | public void keyPressed(final KeyEvent e) { | ||
componentsContainer = (JComponent) getParent(); | componentsContainer = (JComponent) getParent(); | ||
− | //componentsContainer might use the event | + | //componentsContainer might use the keyPressed event |
//to delete the component: | //to delete the component: | ||
componentsContainer.dispatchEvent(e); | componentsContainer.dispatchEvent(e); | ||
− | |||
} | } | ||
}; | }; | ||
Zeile 105: | Zeile 127: | ||
@Override | @Override | ||
public void componentResized(final ComponentEvent e) { | public void componentResized(final ComponentEvent e) { | ||
− | + | ((JComponent) e.getSource()).revalidate(); | |
− | componentsContainer = (JComponent) | + | componentsContainer = (JComponent) getParent(); |
− | componentsContainer. | + | //componentsContainer might use the componentResized event |
+ | //to transfer focus to the resizing component: | ||
+ | if(componentsContainer != null){ | ||
+ | componentsContainer.dispatchEvent(e); | ||
+ | } | ||
} | } | ||
@Override | @Override | ||
public void componentMoved(final ComponentEvent e) { | public void componentMoved(final ComponentEvent e) { | ||
− | + | ((JComponent) e.getSource()).revalidate(); | |
− | |||
} | } | ||
}; | }; | ||
Zeile 119: | Zeile 144: | ||
} | } | ||
+ | /* Move and resize this component. | ||
+ | * This method has been overridden to implement the "snap to grid" option. | ||
+ | */ | ||
@Override | @Override | ||
− | public void reshape(final int x, final int y, final int width, final int height) { | + | public void reshape(final int x, final int y, |
+ | final int width, final int height) { | ||
if (snapToGrid) { | if (snapToGrid) { | ||
− | int | + | //convert all parameters to multiples of MARGIN: |
− | int | + | int gridx = x / MARGIN * MARGIN; |
− | int | + | int gridy = y / MARGIN * MARGIN; |
− | int | + | int gridwidth = width / MARGIN * MARGIN; |
− | if ( | + | int gridheight = height / MARGIN * MARGIN; |
− | + | //if not horizontally on the grid, round up the grid width: | |
+ | if (gridx != x && gridwidth != width) { | ||
+ | gridwidth += MARGIN; | ||
} | } | ||
− | if ( | + | //if not vertically on the grid, round up the grid height: |
− | + | if (gridy != y && gridheight != height) { | |
+ | gridheight += MARGIN; | ||
} | } | ||
− | super.reshape( | + | //snap to the grid: |
− | }else{ | + | super.reshape(gridx, gridy, gridwidth, gridheight); |
+ | } else { | ||
super.reshape(x, y, width, height); | super.reshape(x, y, width, height); | ||
} | } | ||
Zeile 144: | Zeile 177: | ||
public void setSnapToGrid(final boolean snapToGrid) { | public void setSnapToGrid(final boolean snapToGrid) { | ||
this.snapToGrid = snapToGrid; | this.snapToGrid = snapToGrid; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
Zeile 190: | Zeile 211: | ||
public boolean isFocused() { | public boolean isFocused() { | ||
return focused; | return focused; | ||
+ | } | ||
+ | |||
+ | public Rectangle getComponentRect() { | ||
+ | Insets insets = getInsets(); | ||
+ | Rectangle rect = getBounds(); | ||
+ | rect.x += insets.left; | ||
+ | rect.y += insets.top; | ||
+ | rect.width -= (insets.right + insets.left); | ||
+ | rect.height -= (insets.top + insets.bottom); | ||
+ | return rect; | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | ==PictureDemo== | ||
+ | |||
+ | Die Klasse "PictureDemo" ermöglicht das Laden eines Bildes durch einen Klick auf das Fenster. | ||
+ | |||
+ | [[Datei:PictureDemo1.jpg]] | ||
+ | |||
+ | Das geladene Bild kann man anschließend in der Größe und Position verändern. | ||
+ | |||
+ | [[Datei:PictureDemo.jpg]] | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | /* | ||
+ | * PictureDemo.java | ||
+ | */ | ||
− | |||
import container.JComponentBounds; | import container.JComponentBounds; | ||
import java.awt.*; | import java.awt.*; | ||
Zeile 204: | Zeile 249: | ||
import javax.swing.*; | import javax.swing.*; | ||
+ | |||
+ | //Model | ||
+ | class PictureStorage extends Observable { | ||
+ | |||
+ | private BufferedImage data; | ||
+ | |||
+ | public PictureStorage() { | ||
+ | } | ||
+ | |||
+ | public void loadPicture(final String filename) { | ||
+ | System.out.println("loading " + filename); | ||
+ | SwingWorker<BufferedImage, Void> loadPicture = new SwingWorker<BufferedImage, Void>() { | ||
+ | |||
+ | @Override | ||
+ | protected BufferedImage doInBackground() throws Exception { | ||
+ | try { | ||
+ | data = ImageIO.read(new File(filename)); | ||
+ | } catch (IOException ex) { | ||
+ | System.out.println(ex); | ||
+ | } | ||
+ | return data; | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | protected void done() { | ||
+ | setChanged(); | ||
+ | notifyObservers(data); //sends change notification to the view | ||
+ | } | ||
+ | }; | ||
+ | loadPicture.execute(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //View | ||
class GUI extends JFrame implements Observer { | class GUI extends JFrame implements Observer { | ||
Zeile 227: | Zeile 306: | ||
@Override | @Override | ||
− | public void mousePressed(MouseEvent e) { | + | public void mousePressed(final MouseEvent e) { |
FileDialog fileDialog = new FileDialog(frame); | FileDialog fileDialog = new FileDialog(frame); | ||
fileDialog.setVisible(true); | fileDialog.setVisible(true); | ||
Zeile 242: | Zeile 321: | ||
@Override | @Override | ||
− | protected void paintComponent(Graphics g) { | + | protected void paintComponent(final Graphics g) { |
super.paintComponent(g); | super.paintComponent(g); | ||
// g.drawImage(image, 0, 0, this); | // g.drawImage(image, 0, 0, this); | ||
Zeile 268: | Zeile 347: | ||
} | } | ||
− | + | //Controller | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
public class PictureDemo { | public class PictureDemo { | ||
Zeile 310: | Zeile 359: | ||
} | } | ||
− | public void loadPicture(String file) { | + | public void loadPicture(final String file) { |
model.loadPicture(file); | model.loadPicture(file); | ||
} | } | ||
Zeile 319: | Zeile 368: | ||
@Override | @Override | ||
public void run() { | public void run() { | ||
− | new PictureDemo(); | + | PictureDemo pictureDemo = new PictureDemo(); |
} | } | ||
}; | }; | ||
Zeile 326: | Zeile 375: | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
− | |||
[[Kategorie:Swing]] | [[Kategorie:Swing]] | ||
[[Kategorie:Java-Codeschnipsel]] | [[Kategorie:Java-Codeschnipsel]] |
Aktuelle Version vom 8. April 2018, 11:47 Uhr
Inhaltsverzeichnis
Die Klasse und ein Anwendungsbeispiel
JComponentBounds
Die Klasse JComponentBounds
erlaubt es, JComponent
s zu verschieben und in der Grösse zu verändern. Die Klasse "PictureDemo" weiter unten zeigt ein Anwendungsbeispiel.
/*
* JComponentBounds.java
*
* This class aims at making any JComponent resizable
* simply by putting it inside a JInternalFrame.
* The wrapped JComponent is made moveable
* by means of a MouseInputAdapter.
* The class includes a "snap to grid" option.
*
* author: Andre Uhres
* update April 15, 2010 at 6:00
* update December 21, 2010 at 15:00
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.basic.*;
public class JComponentBounds extends JInternalFrame {
public static final int FOCUS_GAINED = 97531;
private JComponent componentsContainer;
private boolean focused;
private JComponent comp;
private static final Color TRANSPARENT = new Color(0.0f, 0.0f, 0.0f, 0.0f);
public static final int MARGIN = 5;
private KeyAdapter kl;
private MouseInputAdapter ml;
private ComponentAdapter cl;
private boolean snapToGrid;
public JComponentBounds() {
this(new JLabel("jComponentBounds"));
}
public JComponentBounds(final JComponent comp) {
this(comp, 0, 0, false);
}
public JComponentBounds(final JComponent comp, final boolean focused) {
this(comp, 0, 0, focused);
}
public JComponentBounds(final JComponent comp, final int x, final int y,
final boolean focused) {
super();
this.comp = comp;
this.focused = focused;
setBounds(x, y,
comp.getPreferredSize().width, comp.getPreferredSize().height);
setResizable(true);
setVisible(true);
setOpaque(false);
setBackground(TRANSPARENT);
((BasicInternalFrameUI) getUI()).setNorthPane(null);
setBorder(BorderFactory.createEmptyBorder(
MARGIN, MARGIN, MARGIN, MARGIN));
comp.setFocusable(true);
add(comp);
ml = new MouseInputAdapter() {
private Point p1;
@Override
public void mousePressed(final MouseEvent e) {
p1 = e.getPoint();
componentsContainer = (JComponent) getParent();
e.setSource(JComponentBounds.this);
//componentsContainer might use the mousePressed event
//to take hidden components to the top:
componentsContainer.dispatchEvent(e);
}
@Override
public void mouseReleased(final MouseEvent e) {
componentsContainer = (JComponent) getParent();
e.setSource(JComponentBounds.this);
//componentsContainer might use the mouseReleased event
//to take hidden components to the top:
componentsContainer.dispatchEvent(e);
}
@Override
public void mouseDragged(final MouseEvent e) {
if (!JComponentBounds.this.isFocused()) {
return;
}
//drag operation:
Point p2 = e.getPoint();
Point loc = getLocation();
loc.translate(p2.x - p1.x, p2.y - p1.y);
setLocation(loc);
componentsContainer = (JComponent) getParent();
//auto scroll:
componentsContainer.scrollRectToVisible(
new Rectangle(loc.x, loc.y, getWidth(), getHeight()));
//componentsContainer might use the focusGained event
//to keep the dragged component in front:
FocusListener[] focusListeners = componentsContainer.getFocusListeners();
if (focusListeners != null && focusListeners.length > 0) {
FocusListener fl = focusListeners[0];
fl.focusGained(
new FocusEvent(JComponentBounds.this,
JComponentBounds.FOCUS_GAINED));
}
}
};
kl = new KeyAdapter() {
@Override
public void keyPressed(final KeyEvent e) {
componentsContainer = (JComponent) getParent();
//componentsContainer might use the keyPressed event
//to delete the component:
componentsContainer.dispatchEvent(e);
}
};
cl = new ComponentAdapter() {
@Override
public void componentResized(final ComponentEvent e) {
((JComponent) e.getSource()).revalidate();
componentsContainer = (JComponent) getParent();
//componentsContainer might use the componentResized event
//to transfer focus to the resizing component:
if(componentsContainer != null){
componentsContainer.dispatchEvent(e);
}
}
@Override
public void componentMoved(final ComponentEvent e) {
((JComponent) e.getSource()).revalidate();
}
};
addAllListeners();
}
/* Move and resize this component.
* This method has been overridden to implement the "snap to grid" option.
*/
@Override
public void reshape(final int x, final int y,
final int width, final int height) {
if (snapToGrid) {
//convert all parameters to multiples of MARGIN:
int gridx = x / MARGIN * MARGIN;
int gridy = y / MARGIN * MARGIN;
int gridwidth = width / MARGIN * MARGIN;
int gridheight = height / MARGIN * MARGIN;
//if not horizontally on the grid, round up the grid width:
if (gridx != x && gridwidth != width) {
gridwidth += MARGIN;
}
//if not vertically on the grid, round up the grid height:
if (gridy != y && gridheight != height) {
gridheight += MARGIN;
}
//snap to the grid:
super.reshape(gridx, gridy, gridwidth, gridheight);
} else {
super.reshape(x, y, width, height);
}
}
public boolean isSnapToGrid() {
return snapToGrid;
}
public void setSnapToGrid(final boolean snapToGrid) {
this.snapToGrid = snapToGrid;
}
private void addAllListeners() {
comp.addMouseListener(ml);
comp.addMouseMotionListener(ml);
comp.addKeyListener(kl);
addComponentListener(cl);
}
public void removeAllListeners() {
comp.removeMouseListener(ml);
comp.removeMouseMotionListener(ml);
comp.removeKeyListener(kl);
removeComponentListener(cl);
}
public void setComponent(final JComponent comp) {
//remove old component:
removeAllListeners();
remove(this.comp);
//add new component:
this.comp = comp;
comp.setFocusable(true);
add(comp);
addAllListeners();
}
public void setFocused(final boolean focused) {
this.focused = focused;
repaint();
}
public boolean isFocused() {
return focused;
}
public Rectangle getComponentRect() {
Insets insets = getInsets();
Rectangle rect = getBounds();
rect.x += insets.left;
rect.y += insets.top;
rect.width -= (insets.right + insets.left);
rect.height -= (insets.top + insets.bottom);
return rect;
}
}
PictureDemo
Die Klasse "PictureDemo" ermöglicht das Laden eines Bildes durch einen Klick auf das Fenster.
Das geladene Bild kann man anschließend in der Größe und Position verändern.
/*
* PictureDemo.java
*/
import container.JComponentBounds;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
//Model
class PictureStorage extends Observable {
private BufferedImage data;
public PictureStorage() {
}
public void loadPicture(final String filename) {
System.out.println("loading " + filename);
SwingWorker<BufferedImage, Void> loadPicture = new SwingWorker<BufferedImage, Void>() {
@Override
protected BufferedImage doInBackground() throws Exception {
try {
data = ImageIO.read(new File(filename));
} catch (IOException ex) {
System.out.println(ex);
}
return data;
}
@Override
protected void done() {
setChanged();
notifyObservers(data); //sends change notification to the view
}
};
loadPicture.execute();
}
}
//View
class GUI extends JFrame implements Observer {
private PictureDemo demo;
private JComponent picture;
private JComponentBounds pictureBounds;
private GUI frame;
private Image image;
public GUI(final PictureDemo demo) {
super();
this.demo = demo;
this.init();
}
private void init() {
frame = this;
setTitle("Demo: click to load picture");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(final MouseEvent e) {
FileDialog fileDialog = new FileDialog(frame);
fileDialog.setVisible(true);
String dir = fileDialog.getDirectory();
String file = fileDialog.getFile();
if (dir != null && file != null) {
demo.loadPicture(dir + file);
}
}
});
//configure picture:
setLayout(null);
picture = new JLabel() {
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
// g.drawImage(image, 0, 0, this);
g.drawImage(image, 0, 0, pictureBounds.getWidth(), pictureBounds.getHeight(), this);
}
};
picture.setPreferredSize(new Dimension(100, 100));
pictureBounds = new JComponentBounds(picture, 10, 10, true);
pictureBounds.setMinimumSize(new Dimension(40, 20));
// pictureBounds.setSnapToGrid(true);
add(pictureBounds);
}
public void update(final Observable observable, final Object arg) {
image = (Image) arg;
if (image == null) {
JOptionPane.showMessageDialog(this, "Picture not found");
} else {
pictureBounds.setSize(image.getWidth(null), image.getHeight(null));
picture.setOpaque(true);
picture.setBackground(Color.LIGHT_GRAY);
picture.repaint();
}
}
}
//Controller
public class PictureDemo {
private PictureStorage model;
public PictureDemo() {
model = new PictureStorage();
GUI gui = new GUI(this);
model.addObserver(gui);
gui.setVisible(true);
}
public void loadPicture(final String file) {
model.loadPicture(file);
}
public static void main(final String[] args) {
Runnable gui = new Runnable() {
@Override
public void run() {
PictureDemo pictureDemo = new PictureDemo();
}
};
//GUI must start on EventDispatchThread:
SwingUtilities.invokeLater(gui);
}
}