我刚开始为我自己使用一个记录工具,它可以记录健身房/跑步的统计数据,我在 swing/awt 方面的唯一经验是你可以完全控制 Graphics2D 对象的游戏的主动渲染,而不是依赖于实现带有覆盖油漆的摆动组件。
无论如何,我希望创建一个虚拟 JComponent,我可以将它添加到我的一个面板(此面板将显示图形、统计信息等,具体取决于我从另一个带有选项的不同侧面板中选择的内容),除了监听鼠标事件前面提到的面板并在鼠标拖动上绘制一个选择矩形,以便在存在更高分辨率时可以放大数据。我只是不知道如何,我已将组件添加到面板中,但它在面板内没有注册任何内容,而是似乎有一个仅限于面板/框架底部的本地空间。
这是组件
package gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MarkerRectangle extends JComponent implements MouseListener,
MouseMotionListener {
private boolean draw;
private int startX, endX, startY, endY;
private Color color = new Color(0, 255, 0, 100);
public MarkerRectangle(int width, int height) {
setPreferredSize(new Dimension(width, height));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("Mouse clicked@ " + e.getX() + "," + e.getY());
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Mouse entered @ " + e.getX() + "," + e.getY());
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("Mouse left @ " + e.getX() + "," + e.getY());
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("Mouse pressed@ " + e.getX() + "," + e.getY());
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("Mouse was released @ " + e.getX() + "," + e.getY());
}
@Override
public void mouseDragged(MouseEvent e) {
System.out.println("Mouse being dragged, currently@ " + e.getX() + ","
+ e.getY());
}
@Override
public void mouseMoved(MouseEvent e) {
System.out.println("I registered a move@ " + e.getX() + "," + e.getY());
}
@Override
// Draw rectangle
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
面板_
public class GraphPane extends JPanel {
public GraphPane(Graph graph) {
this.add(graph);
this.add(new MarkerRectangle(800, 600));
this.setBackground(Color.gray);
this.setPreferredSize(new Dimension(800, 600));
}
}
该图,保存随机数据atm
public class Graph extends JComponent {
private GeneralPath data;
private Stroke stroke;
public Graph() {
this.data = new GeneralPath();
this.stroke = new BasicStroke(3f);
this.setPreferredSize(new Dimension(750, 550));
init();
}
private void init() {
data.moveTo(0, 0);
double cntr = 0;
double[][] points = new double[10][1];
for (double[] point : points) {
cntr += 100;
point[0] = Math.random() * 100;
point[1] = Math.random() * 100;
data.lineTo(cntr, point[1]);
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(stroke);
g2d.draw(data);
g2d.dispose();
}
}
我想实现类似上面的东西,因为最终我想象 GUI 变得非常复杂和简单的事件,比如绘制一个矩形来标记数据不应该在主控制器中(以防止大量的 if 测试和代码中的混乱)。
我得到的截图:
我想要的是:
编辑 虽然下面接受的答案是更好的解决方案,但如果有人可能想要使用它,我会发布这个。如果您将 prefferedSize 的大小调整为更小,它将不起作用。
public class Test {
public static void main(String[] args) {
GeneralJFrame frame = new GeneralJFrame(1200, 800);
frame.addPanel(new GraphPane(new Graph()), BorderLayout.CENTER);
frame.addPanel(new ButtonPane(), BorderLayout.SOUTH);
frame.addPanel(new ButtonPane(), BorderLayout.SOUTH);
frame.addPanel(new ButtonPane(), BorderLayout.WEST);
frame.addPanel(new ButtonPane(), BorderLayout.EAST);
frame.addPanel(new ButtonPane(), BorderLayout.NORTH);
frame.start();
}
}
public class GraphPane extends JPanel {
public GraphPane(Graph graph) {
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridheight = GridBagConstraints.REMAINDER;
c.gridx = 0;
c.gridy = 0;
this.setLayout(new GridBagLayout());
this.add(graph);
this.add(new MarkerRectangle(), c);
this.setBackground(new Color(205, 201, 201));
}
}
public class MarkerRectangle extends JComponent implements MouseListener,
MouseMotionListener {
private boolean draw;
private int startX, endX, startY, endY;
public MarkerRectangle() {
this.addMouseListener(this);
this.addMouseMotionListener(this);
setOpaque(false);
setPreferredSize(new Dimension(800, 600));
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
startX = e.getX();
startY = e.getY();
draw = true;
}
@Override
public void mouseReleased(MouseEvent e) {
draw = false;
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
endX = e.getX();
endY = e.getY();
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
// Draw rectangle
protected void paintComponent(Graphics g) {
System.out.println(getSize());
if (!draw)
return;
int w = endX-startX;
int h = endY - startY;
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(255, 165, 0));
g2d.fillRect(startX, startY, w, h);
g2d.dispose();
}
}
public class ButtonPane extends JPanel {
public ButtonPane() {
add(new JButton("HELLO"));
setBackground(Color.gray);
setBorder(BorderFactory.createEtchedBorder(Color.white,
Color.gray.darker()));
}
}
public class GeneralJFrame {
private JFrame frame;
public GeneralJFrame(int width, int height) {
this.frame = new JFrame("Le Muscles");
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void addPanel(JPanel panel, String location) {
this.frame.add(panel, location);
}
public void start() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
输出:(用鼠标拖动橙色)