如何将MouseListener添加到Java Swing Canvas上的项目
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何将MouseListener添加到Java Swing Canvas上的项目,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7156字,纯文字阅读大概需要11分钟。
内容图文
我想创建一个Java面板,用于创建用户单击的对象.由于我的实际应用程序使用MVC方法,我也希望这些对象能够在模型更改时重新绘制自己,并提供更改其属性的菜单.
我认为控制x和y位置的最佳方法是采用基于画布的方法,JPanel从paintComponent方法调用这些对象的draw方法.然而,这只会在画布上绘制形状,并且不会添加对象本身而失去控制对象属性的所有能力.如果有人能告诉我最适合自己想做的事情,我将非常感激.
我已经创建了一些示例代码,可以在下面看到.单击时,我希望圆圈改变颜色,这是使用MouseListener实现的(它基本上代表在这个小例子中更改模型属性).此外,我还想确保放大/缩小仍然适用于任何示例代码/建议可以提供,所以我添加了按钮来放大和缩小对象作为快速测试.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.geom.Ellipse2D;
public class Main {
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ExamplePanel panel = new ExamplePanel();
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
//I could not get this to with when it extended JLayeredPane
private static class ExamplePanel extends JPanel {
private static final int maxX = 500;
private static final int maxY = 500;
private static double zoom = 1;
private static final Circle circle = new Circle(100, 100);
public ExamplePanel() {
this.setPreferredSize(new Dimension(maxX, maxY));
this.setFocusable(true);
Button zoomIn = new Button("Zoom In");
zoomIn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
zoom += 0.1;
repaint();
}
});
add(zoomIn);
Button zoomOut = new Button("Zoom Out");
zoomOut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
zoom -= 0.1;
repaint();
}
});
add(zoomOut);
// add(circle); // Comment back in if using JLayeredPane
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.scale(zoom, zoom);
super.paintComponent(g);
circle.paint(g); // Comment out if using JLayeredPane
}
}
static class Circle extends JPanel {
private Color color = Color.RED;
private final int x;
private final int y;
private static final int DIMENSION = 100;
public Circle(int x, int y) {
// setBounds(x, y, DIMENSION, DIMENSION);
this.x = x;
this.y = y;
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
color = Color.BLUE;
}
@Override
public void mouseReleased(MouseEvent e) {
}
});
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(color);
g2.fillOval(x, y, DIMENSION, DIMENSION);
}
// I had some trouble getting this to work with JLayeredPane even when setting the bounds
// In the constructor
// @Override
// public void paintComponent(Graphics g) {
// Graphics2D g2 = (Graphics2D) g;
// g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// g2.setPaint(color);
// g2.fillOval(x, y, DIMENSION, DIMENSION);
// }
@Override
public Dimension getPreferredSize(){
return new Dimension(DIMENSION, DIMENSION);
}
}
}
顺便说一句,我确实尝试使用JLayeredPane(因为我也喜欢将对象分层)但是无法让我的对象进行渲染.我知道它没有默认的布局管理器,所以试着在构造函数的圆圈中调用setBounds,但遗憾的是它没有用.我知道使用布局管理器更好,但似乎找不到适合我需求的布局管理器!
提前致谢.
解决方法:
不要覆盖paint组件,使用paintComponent并且不要忘记调用super.paintComponent
组件已经具有“位置”的概念,因此在绘制时,组件的左上角位置实际上是0x0
你正在做的事实上是超越你组件的边界
例如,如果您将圆圈放置在100×100然后…
g2.fillOval(x, y, DIMENSION, DIMENSION);
您实际上将以200×200开始绘画(100表示??组件的实际位置,100表示??额外定位).
而是使用
g2.fillOval(x, y, DIMENSION, DIMENSION);
然后回去尝试使用JLayeredPane.
您实际上可以编写自己的布局管理器,它获取组件的位置及其首选大小并更新组件边界,然后将其应用于JLayeredPane.这为您提供了绝对布局的“好处”,但让您了解Swing如何在事情发生变化时更新其组件.
你应该小心做任何事情……
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Graphics上下文是共享资源.这意味着,当您绘制下一个组件时,您应用的任何内容仍然有效.这可能会产生一些奇怪的结果.
而是尝试使用……
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//...
g2.dispose();
更新
对于缩放,我会仔细看看JXLayer(或Java 7中的JLayer)
JXLayer(以及优秀的PBar扩展)已经上网了,所以你可以从here获取一份副本
(我试图找到一个更好的例子,但这是我能用有限时间做的最好的事情)
更新了工作缩放示例
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jdesktop.jxlayer.JXLayer;
import org.pbjar.jxlayer.demo.TransformUtils;
import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel;
public class TestJLayerZoom {
public static void main(String[] args) {
new TestJLayerZoom();
}
public TestJLayerZoom() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JXLayer<JComponent> layer;
private DefaultTransformModel transformModel;
private JPanel content;
public TestPane() {
content = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
JLabel label = new JLabel("Hello");
JTextField field = new JTextField("World", 20);
content.add(label, gbc);
content.add(field, gbc);
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
final JSlider slider = new JSlider(50, 200);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int value = slider.getValue();
double scale = value / 100d;
transformModel.setScale(scale);
}
});
content.add(slider, gbc);
transformModel = new DefaultTransformModel();
transformModel.setScaleToPreferredSize(true);
Map<RenderingHints.Key, Object> hints = new HashMap<>();
//hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//hints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
//hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
layer = TransformUtils.createTransformJXLayer(content, transformModel, hints);
setLayout(new BorderLayout());
add(layer);
}
}
}
我已经留下了渲染提示来演示它们的用法,但是我发现它们在文本字段中用光标的位置搞定了,但是你可能想玩一个游戏
内容总结
以上是互联网集市为您收集整理的如何将MouseListener添加到Java Swing Canvas上的项目全部内容,希望文章能够帮你解决如何将MouseListener添加到Java Swing Canvas上的项目所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。