- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 Java 新手,正在自学。我在这一点上陷入困境。我创建了一个非常基本的绘图应用程序,但我的 friend 告诉我,当我将所有内容都放在一个 *.java 文件中时,您可以看出我是一名初级程序员,因为我并没有真正使用面向对象编程:D 所以我决定将我的代码分成不同的文件。但现在代码不起作用(显然)。
所以我有 Main.java 文件,它为程序 (JFrame) 创建一个窗口,在该 JFrame 内部有 2 个面板,一个位于 BorderLayout.WEST,第二个位于 CENTER。 .WEST 上的那个是侧栏(带有按钮等),.CENTER 上的那个是主绘图板:
Main.java 文件(公共(public)类 Main):
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.*;
public class Main {
private Paint myPaint;
private menuSideBar sidePanel;
Main(){
JFrame ramka = new JFrame("Paint Application");
sidePanel = new menuSideBar(); //this is the sidebar
myPaint = new Paint(); // this is the drawing board
ramka.getContentPane().add(sidePanel, BorderLayout.WEST);
ramka.getContentPane().add(myPaint, BorderLayout.CENTER);
ListenForWindow lForWindow = new ListenForWindow();
ramka.addWindowListener(lForWindow);
ramka.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
ramka.setSize(1400, 800);
ramka.setLocationRelativeTo(null);
ramka.setVisible(true);
}
private class ListenForWindow implements WindowListener{
public void windowOpened(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
int closing = JOptionPane.showConfirmDialog(null, "Exit program?", "Exit", JOptionPane.YES_NO_OPTION);
if (closing == JOptionPane.YES_OPTION){
System.exit(0);
}
}
public void windowClosed(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
}
public static void main(String[] args){
new Main();
}
}
然后我就有了画板,位于文件 Paint.java(公共(public)类 Paint)中:
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class Paint extends JComponent {
private static final long serialVersionUID = 1L;
private BufferedImage bimage;
private Graphics2D g2;
private int whichShape;
private int oldX, oldY, newX, newY;
private int w, h;
private Color cColor;
Paint() {
ListenForMouse lForMouse = new ListenForMouse();
this.addMouseListener(lForMouse);
this.addMouseMotionListener(lForMouse);
}
public void paintComponent(Graphics g){
if (bimage == null){
bimage = new BufferedImage(getSize().width, getSize().height, BufferedImage.TYPE_INT_ARGB);
g2 = (Graphics2D) bimage.getGraphics();
g2.setBackground(Color.WHITE);
g2.setColor(Color.BLACK);
clear();
}
g.drawImage(bimage, 0, 0, null);
}
public void clear(){
g2.clearRect(0, 0, getSize().width, getSize().height);
repaint();
}
public void draw(){
w = newX - oldX;
h = newY - oldY;
if (w<0){
w = w * (-1);
}
if (h<0){
h = h * (-1);
}
switch (whichShape) {
case 1:
check();
g2.drawRect(oldX, oldY, w, h);
repaint();
break;
case 2:
check();
g2.drawRoundRect(oldX, oldY, w, h, 40, 40);
repaint();
break;
case 3:
check();
g2.drawOval(oldX, oldY, w, h);
repaint();
break;
case 4:
check();
g2.fillRect(oldX, oldY, w, h);
repaint();
break;
case 5:
check();
g2.fillRoundRect(oldX, oldY, w, h, 20, 20);
repaint();
break;
case 6:
check();
g2.fillOval(oldX, oldY, w, h);
repaint();
break;
}
}
public void rectangle(){
whichShape = 1;
}
public void roundedrectangle(){
whichShape = 2;
}
public void oval(){
whichShape = 3;
}
public void filledrectangle(){
whichShape = 4;
}
public void filledroundedrectangle(){
whichShape = 5;
}
public void filledoval(){
whichShape = 6;
}
public void colorChooser(){
cColor = JColorChooser.showDialog(null, "Choose color", Color.black);
g2.setColor(cColor);
}
public void check(){
if (oldX > newX){
int z;
z = oldX;
oldX = newX;
newX = z;
}
if (oldY > newY){
int z;
z = oldY;
oldY = newY;
newY = z;
}
}
public class ListenForMouse implements MouseListener, MouseMotionListener{
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if (whichShape == 1 || whichShape == 2 || whichShape == 3 || whichShape == 4 || whichShape == 5 || whichShape == 6){
oldX = e.getX();
oldY = e.getY();
}
}
public void mouseReleased(MouseEvent e) {
if (whichShape == 1 || whichShape == 2 || whichShape == 3 || whichShape == 4 || whichShape == 5 || whichShape == 6){
newX = e.getX();
newY = e.getY();
draw();
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
}
后面还有侧边栏,它在menuSideBar.java文件中(公共(public)类menuSideBar),这个类读取了另外4个类(我要添加4个不同的菜单,这里只展示一个例子):
import javax.swing.*;
public class menuSideBar extends JPanel {
private static final long serialVersionUID = 1L;
sideBar1 sb1;
//sideBar2 sb2;
//sideBar3 sb3;
//sideBar4 sb4;
menuSideBar(){
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
sb1 = new sideBar1();
//sb2 = new sideBar2();
//sb3 = new sideBar3();
//sb4 = new sideBar4();
this.add(sb1);
//this.add(sb2);
//this.add(sb3);
//this.add(sb4);
}
}
这个 sideBar1.java 文件(公共(public)类 sideBar1)包含 JButtons,其中 ActionListeners 引用 Paint.java 文件中的方法:
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class sideBar1 extends JPanel {
private static final long serialVersionUID = 1L;
Paint myPaint;
JButton pencilBut, brushBtn, bckpaintBtn, eraserBtn, textBtn, rectBtn, roundedrectBtn, ovalBtn, frectBtn, fovalBtn, froundedrectBtn, lineBtn;
sideBar1(){
Border border = BorderFactory.createTitledBorder("Paint");
this.setBorder(border);
this.setLayout(new GridLayout(0,3));
myPaint = new Paint();
ListenForButton lForButton = new ListenForButton();
pencilBut = new JButton("pencil");
pencilBut.addActionListener(lForButton);
brushBtn = new JButton("brush");
brushBtn.addActionListener(lForButton);
bckpaintBtn = new JButton("background paint");
bckpaintBtn.addActionListener(lForButton);
eraserBtn = new JButton("eraser");
eraserBtn.setIcon(icon_eraser);
eraserBtn.addActionListener(lForButton);
textBtn = new JButton("text");
textBtn.addActionListener(lForButton);
lineBtn = new JButton("line");
lineBtn.addActionListener(lForButton);
rectBtn = new JButton("rectangle");
rectBtn.addActionListener(lForButton);
roundedrectBtn = new JButton("rounded rectangle");
roundedrectBtn.addActionListener(lForButton);
ovalBtn = new JButton("oval");
ovalBtn.addActionListener(lForButton);
frectBtn = new JButton("filled rectangle");
frectBtn.addActionListener(lForButton);
froundedrectBtn = new JButton("filled rounded rectangle");
froundedrectBtn.addActionListener(lForButton);
fovalBtn = new JButton("filled oval");
fovalBtn.addActionListener(lForButton);
this.add(pencilBut);
this.add(brushBtn);
this.add(bckpaintBtn);
this.add(eraserBtn);
this.add(textBtn);
this.add(lineBtn);
this.add(rectBtn);
this.add(roundedrectBtn);
this.add(ovalBtn);
this.add(frectBtn);
this.add(froundedrectBtn);
this.add(fovalBtn);
}
public class ListenForButton implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == brushBtn){
} else if (e.getSource() == bckpaintBtn){
} else if (e.getSource() == eraserBtn){
} else if (e.getSource() == textBtn){
} else if (e.getSource() == lineBtn){
} else if (e.getSource() == rectBtn){
System.out.println("rectangle");
myPaint.rectangle();
} else if (e.getSource() == roundedrectBtn){
myPaint.roundedrectangle();
} else if (e.getSource() == ovalBtn){
myPaint.oval();
} else if (e.getSource() == frectBtn){
myPaint.filledrectangle();
} else if (e.getSource() == froundedrectBtn){
myPaint.filledroundedrectangle();
} else if (e.getSource() == fovalBtn){
myPaint.filledoval();
}
}
}
}
现在,当我执行代码时,所有内容都会顺利加载,我可以看到所有面板和内部的所有组件,但是当我单击按钮时,什么也没有发生。我猜这与继承有关,或者实际上我有几个问题:
谢谢!抱歉,如果这对您来说似乎很明显,但是书籍或教程中的所有示例都有非常简短的继承示例和非常简单的示例,并且不知何故我无法将这些简单的示例转移到我的代码中。谢谢!
最佳答案
您的主要问题是,当您只需要并且应该有一个 Paint 对象时,您正在创建两个 Paint 对象。要亲自检查这一点,请搜索此页面以了解您看到 new Paint()
的次数。你应该只在代码中看到它一次,而你却看到了它两次。
为什么这很重要?一个 Paint 对象显示在 GUI 中,另一个则不显示,但在 ActionListener 中按下按钮时会调用其方法。在非显示对象上调用方法不会转换为显示对象中的可见响应。
一个简单但错误的解决方案是使您的绘图变量静态并在任何地方共享它。这是错误的,因为您会失去 OOP 的好处并增加错误的风险。更好的方法是将可视化 Paint 对象的引用传递到需要的 ActionListener 中,以便仅创建一个 Paint 对象,并在监听器中调用与显示的同一 Paint 对象上的方法。
更具体,更改此:
sidePanel = new menuSideBar(); //this is the sidebar
myPaint = new Paint(); // this is the drawing board
对此:
myPaint = new Paint(); // call this first
sidePanel = new menuSideBar(myPaint); // and pass it in
在sideBar构造函数中(该类应重命名为SideBar),使用参数:
public sideBar(Paint myPaint) {
this.myPaint = myPaint;
// .... all other constructor code
}
并从 sideBar 中删除 new Paint()
。
关于Java:Paint应用程序,代码不起作用,我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40556548/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!