java - 在 Java 中调用类中的方法
问题描述
我有一个非常基本的问题:我的MainDriver
班级希望在按下Line
按钮时运行班级Line
;但是,我知道我们不能运行整个班级,所以如果有其他方法可以实现这一点,请告诉我。
以下是MainDriver
类;我用星号突出显示了相关位。
package javafx.scene;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
//import java.awt.*;
class MainDriver extends JFrame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
// create a frame
static JFrame frame;
// main function
public static void main(String args[])
{
// create a frame
frame = new JFrame("DrawShapes");
try {
// set look and feel
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e) {
System.err.println(e.getMessage());
}
// create a object of class
Line line = new Line();
// create number buttons and some operators
JButton b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bs, bd, bm, be, beq;
// create number buttons
b0 = new JButton("line");
b1 = new JButton("circle");
b2 = new JButton("triangle");
b3 = new JButton("rectangle");
b4 = new JButton("quadrilateral");
b5 = new JButton("move");
b6 = new JButton("copy");
b7 = new JButton("delete");
b8 = new JButton("random");
b9 = new JButton("import");
ba = new JButton("export");
bs = new JButton("");
bd = new JButton("/");
bm = new JButton("*");
beq = new JButton("C");
// create . button
be = new JButton(".");
// create a panel
JPanel p = new JPanel();
// add action listeners
b0.addActionListener(line);
//add more later
// add elements to panel
p.add(b0);
p.add(ba);
p.add(b1);
p.add(b2);
p.add(b3);
p.add(bs);
p.add(b4);
p.add(b5);
p.add(b6);
p.add(bm);
p.add(b7);
p.add(b8);
p.add(b9);
p.add(bd);
p.add(be);
p.add(b0);
p.add(beq);
// set Background of panel
p.setBackground(Color.blue);
// add panel to frame
frame.add(p);
frame.setSize(450, 400);
}
public void actionPerformed(ActionEvent e)
{
String s = e.getActionCommand();
*************************
if (s.equals("line")) {
//Im not sure how to implement the object here
}
***************************
}
}
这是Line
课程
package javafx.scene;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Line extends JPanel implements MouseListener,ActionListener{
private int x,y,x2,y2,a=1;
public Line(){
super();
addMouseListener(this);
}
public void paint(Graphics g){
int w = x2 - x ;
int h = y2 - y ;
int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0 ;
if (w<0) dx1 = -1 ; else if (w>0) dx1 = 1 ;
if (h<0) dy1 = -1 ; else if (h>0) dy1 = 1 ;
if (w<0) dx2 = -1 ; else if (w>0) dx2 = 1 ;
int longest = Math.abs(w) ;
int shortest = Math.abs(h) ;
if (!(longest>shortest)) {
longest = Math.abs(h) ;
shortest = Math.abs(w) ;
if (h<0) dy2 = -1 ; else if (h>0) dy2 = 1 ;
dx2 = 0 ;
}
int numerator = longest >> 1 ;
for (int i=0;i<=longest;i++) {
g.fillRect(x,y,1,1);
numerator += shortest ;
if (!(numerator<longest)) {
numerator -= longest ;
x += dx1 ;
y += dy1 ;
} else {
x += dx2 ;
y += dy2 ;
}
}
}
public void mouseClicked(MouseEvent mouse) {
if (a == 1) {
a = 0;
x = x2 = mouse.getX();
y = y2 = mouse.getY();
} else {
a = 1;
x = x2;
y = y2;
x2 = mouse.getX();
y2 = mouse.getY();
repaint();
}
}
public void mouseEntered(MouseEvent mouse){ }
public void mouseExited(MouseEvent mouse){ }
public void mousePressed(MouseEvent mouse){ }
public void mouseReleased(MouseEvent mouse){ }
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
解决方案
这是一个关于如何去做的例子:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class Main {
private static void drawPoint(final Graphics g, final Point p) {
g.drawLine(p.x - 10, p.y, p.x + 10, p.y);
g.drawLine(p.x, p.y - 10, p.x, p.y + 10);
}
private static void drawLine(final Graphics g, final Point p1, final Point p2) {
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
public static interface ShapeByPoints {
int getPointCount();
void draw(final Graphics g, final Point... points);
}
public static class DrawPanel extends JPanel {
private final ArrayList<Point> points;
private ShapeByPoints s;
public DrawPanel() {
points = new ArrayList<>();
s = null;
}
public void setShape(final ShapeByPoints s) {
this.s = s;
points.clear();
repaint();
}
public void modifyLastPoint(final Point p) {
points.get(points.size() - 1).setLocation(p);
repaint();
}
public void addPoint(final Point p) {
if (s != null && points.size() == s.getPointCount())
points.clear();
points.add(p);
repaint();
}
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (s != null && s.getPointCount() == points.size())
s.draw(g, points.toArray(new Point[s.getPointCount()]));
else {
points.forEach(p -> drawPoint(g, p));
for (int i = 1; i < points.size(); ++i)
drawLine(g, points.get(i - 1), points.get(i));
}
}
}
public static class EllipseByPoints implements ShapeByPoints {
@Override
public int getPointCount() {
return 2;
}
@Override
public void draw(final Graphics g, final Point... points) {
g.drawOval(Math.min(points[0].x, points[1].x), Math.min(points[0].y, points[1].y), Math.abs(points[1].x - points[0].x), Math.abs(points[1].y - points[0].y));
}
}
public static class PolygonByPoints implements ShapeByPoints {
private final int points;
public PolygonByPoints(final int points) {
this.points = points;
}
@Override
public int getPointCount() {
return points;
}
@Override
public void draw(final Graphics g, final Point... points) {
for (int i = 1; i < this.points; ++i)
drawLine(g, points[i - 1], points[i]);
drawLine(g, points[this.points - 1], points[0]);
}
}
public static class LineByPoints extends PolygonByPoints {
public LineByPoints() {
super(2);
}
}
public static class RectangleByPoints implements ShapeByPoints {
@Override
public int getPointCount() {
return 2;
}
@Override
public void draw(final Graphics g, final Point... points) {
g.drawRect(Math.min(points[0].x, points[1].x), Math.min(points[0].y, points[1].y), Math.abs(points[1].x - points[0].x), Math.abs(points[1].y - points[0].y));
}
}
private static JRadioButton createButton(final String buttonText, final ButtonGroup bg, final DrawPanel dp, final ShapeByPoints s) {
final JRadioButton btn = new JRadioButton(buttonText);
btn.addActionListener(e -> dp.setShape(s));
bg.add(btn);
return btn;
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
final DrawPanel dp = new DrawPanel();
final MouseAdapter ma = new MouseAdapter() {
@Override
public void mousePressed(final MouseEvent mevt) {
dp.addPoint(mevt.getPoint());
}
@Override
public void mouseDragged(final MouseEvent mevt) {
dp.modifyLastPoint(mevt.getPoint());
}
@Override
public void mouseReleased(final MouseEvent mevt) {
dp.modifyLastPoint(mevt.getPoint());
}
};
dp.setPreferredSize(new Dimension(500, 350));
dp.addMouseListener(ma);
dp.addMouseMotionListener(ma);
final ButtonGroup bg = new ButtonGroup();
final JPanel buttons = new JPanel();
buttons.add(createButton("Line", bg, dp, new LineByPoints()));
buttons.add(createButton("Ellipse", bg, dp, new EllipseByPoints()));
buttons.add(createButton("Rectangle", bg, dp, new RectangleByPoints()));
buttons.add(createButton("Triangle", bg, dp, new PolygonByPoints(3)));
buttons.add(createButton("Pentagon", bg, dp, new PolygonByPoints(5)));
//... keep creating buttons here ...
final JPanel contents = new JPanel(new BorderLayout());
contents.add(dp, BorderLayout.CENTER);
contents.add(buttons, BorderLayout.PAGE_START);
final JFrame frame = new JFrame("Clicking shapes.");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
笔记:
- 除非有充分的理由,否则不要使用
paint
,这通常不是。在大多数情况下,您要绘制面板,在这种情况下paintComponent
应该足够了。 - 不要忘记首先调用
super.paintComponent
内部paintComponent
覆盖。这应该是第一次调用,因为它会为您从以前的图纸中清除面板。 - 决定是否要添加
JComponent
将绘制形状的 s,或者自己在子类面板中绘制形状。在这种情况下,您似乎正在尝试两者(因为Line extends JPanel
并且您还覆盖了paint
)。在我看来,在这种情况下,使用抽象的形状在一些点之间绘制就可以了。这就是我创建ShapeByPoints
界面的原因。 - Swing 不是线程安全的,这意味着对同一变量的竞争访问之间可能存在条件。为了避免这种情况,您可以在Event Dispatch Thread(或简称EDT )上运行每个与 Swing 相关的操作。要在 EDT 中显式进行调用,请调用 、 等方法
SwingUtilities.invokeLater
……SwingUtilities.invokeAndWait
InternetEventQueue.invokeLater
上有足够多的关于此主题的资料。例如这里。 - 基本上,在我的方法中,所有内容都是从头开始重新设计的(即我没有修改您的示例代码,因为我猜这会花费更多时间,但这只是一个猜测)。
我刚刚创建了ShapeByPoints
指定如何绘制形状的界面(即它需要的点数和draw
绘制方法)。
然后我创建了一个DrawPanel extends JPanel
包含每个操作的状态。例如,如果用户选择要绘制的五边形,他需要 5 个点,但是当他/她只单击两次时会发生什么?DrawPanel
...完成/点击。
DrawPanel
我在框架中添加了一个实例,一个MouseAdapter
用于用户交互的实例和几个按钮来演示这个逻辑。
您现在需要做的就是ShapeByPoints
按照您的喜好实现并将它的实例提供给所DrawPanel
按下按钮的依赖项。我已经做了一些关于如何在代码中执行此操作的示例(如、EllipseByPoints
和LineByPoints
)。RectangleByPoints
PolygonByPoints
最后,作为奖励,我添加了拖动单击点的功能(即不仅单击它们,而且单击并拖动它们)。
希望能帮助到你。
推荐阅读
- python - 使用解析时出现语法错误
- c# - 以自定义格式使用撇号''作为日期
- javascript - 删除父 HTML 元素中的 HTML 元素
- python - 将 Numpy 结构化数组转换为 Pandas 数据帧
- pdf - 将 DataTables 导出为 PDF 重复标题
- android - [[15.0.1,15.0.1]] 的各种其他库正在请求库 com.google.android.gms:play-services-basement,但解析为 11.8.0
- python-3.x - 隐藏窗口(pywinauto)
- php - 函数getImage(); 不在网站上显示图像。
- bots - 遵循说明时 WAS 登录页面错误中的 WAS Slackbot 集成
- php - 带有 HTML2PDF 的表溢出索引