好的,我刚刚习惯OOP,现在正在学习挥杆。我正在制作一个简单的应用程序,该应用程序是2x2网格,包含4张图像(X,O,正方形和三角形),然后单击任意一个将颜色的形状切换为蓝色。
尽管我无法切换到新图像,但我认为它与程序的基本功能有关。
介意吗?
JFrame类:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import javax.swing.JPanel;
public class Frame1 {
public JFrame frame;
Frame1 window = new Frame1();
window.frame.setVisible(true);
}
public Frame1() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 900, 900);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
Squares x = new Squares("images\\black-X.png", "images\\blue-X.png", 0, 0, 450, 450, "x");
Squares o = new Squares("images\\black-O.png", "images\\blue-O.png", 450, 0, 450, 450, "o");
Squares sq = new Squares("images\\black-sq.png", "images\\blue-sq.png", 0, 425, 450, 450, "sq");
Squares tri = new Squares("images\\black-tri.png", "images\\blue-tri.png", 450, 410, 450, 450, "tri");
frame.getContentPane().add(x.getLabel());
frame.getContentPane().add(o.getLabel());
frame.getContentPane().add(sq.getLabel());
frame.getContentPane().add(tri.getLabel());
}
}
Mouselistener类别:
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class clickListener implements MouseListener{
Squares ob = new Squares();
public clickListener(Squares newSquare) {
ob = newSquare;
}
public void mouseClicked(MouseEvent e) {
ob.changePic();
}
}
然后是我为每个图像创建的对象类
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Squares {
String pic1, pic2, name;
int x, y, width, height;
JPanel panel = new JPanel();
JLabel label = new JLabel();
public Squares() {
;
}
public Squares(String pic1, String pic2, int x, int y, int width, int height, String name) {
this.pic1 = pic1;
this.pic2 = pic2;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.name = name;
BufferedImage myPic1 = null;
try {
myPic1 = ImageIO.read(new File(pic1));
} catch (IOException ex) {System.out.println("error in image upload");}
/*
panel.setBounds(x, y, width, height);
panel.add(new JLabel(new ImageIcon(myPic1)));
panel.addMouseListener(new clickListener(this));
*/
label = new JLabel(new ImageIcon(myPic1));
label.setBounds(x, y, width, height);
label.addMouseListener(new clickListener(this));
}
public JLabel getLabel() {
return label;
}
public String getName() {
return this.name;
}
public void changePic() {
JOptionPane.showMessageDialog(null, "change pic reached for " + this.name);
BufferedImage myPic2 = null;
try {myPic2 = ImageIO.read(new File(pic2));}
catch(IOException ex) {System.out.println("error in image upload");}
label = new JLabel(new ImageIcon(myPic2));
label.setBounds(x, y, width, height);
label.repaint();
label.revalidate();
}
}
我最初使用的是包含每个JLabel的JPanels,但为了简化起见,我将它们全部删除了。
是的,任何建议都值得赞赏。谢谢!
答案 0 :(得分:1)
因此,您的changePic
方法中存在“核心”问题
public void changePic() {
JOptionPane.showMessageDialog(null, "change pic reached for " + this.name);
BufferedImage myPic2 = null;
try {
myPic2 = ImageIO.read(new File(pic2));
} catch (IOException ex) {
System.out.println("error in image upload");
}
label = new JLabel(new ImageIcon(myPic2));
label.setBounds(x, y, width, height);
label.repaint();
label.revalidate();
}
在此方法中,您创建了JLabel
的新实例,但是它永远不会添加到屏幕上附加的任何容器中,因此它永远不会显示。
简单的解决方案是仅更改icon
的现有实例的JLabel
属性
public void changePic() {
JOptionPane.showMessageDialog(null, "change pic reached for " + this.name);
BufferedImage myPic2 = null;
try {
myPic2 = ImageIO.read(new File(pic2));
} catch (IOException ex) {
System.out.println("error in image upload");
}
label.setIcon(new ImageIcon(pic2));
}
在遍历代码的同时,我发现一些可以做得更好的事情。
Frame1
的管理主机架实际上不是责任。通过不同的容器可以更好地管理核心功能,这可以使组件分离,并在长期错误的情况下使其更加灵活和可重复使用-您也无需在其他职责中将框架管理的复杂性包括在内。 null
版式。一种更简单的解决方案是使用GridLayout
,因为您提供的实现存在布局问题Squares
不需要知道父容器想要的位置或大小-这并不是父容器直接做出的真正决定。相反,Squares
应该向父容器提供大小调整提示,以便可以就如何布局所有子组件做出更好的决策。 JLabel
本身可以提供此信息。Squares
应该从JLabel
扩展-这纯粹是简单性之一。 JLabel
是显示图像的理想之地,因此这是一个不错的选择,但是在其周围包装一个类只会使它的管理更加麻烦,在这种情况下,几乎没有增加任何价值。对于继承而言,要达成协议,但是在这种情况下,我不确定它将增加更多的价值ClickListener
不需要创建Squares
的实例,它只是构造函数要求任何调用者始终将Squares
的实例传递给它Squares
应该会失败,这将使诊断这些问题变得更加容易,而不是让程序继续以“中断”状态运行状态恕我直言
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Game {
public static void main(String[] args) {
new Game();
}
public Game() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GamePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class GamePane extends JPanel {
public GamePane() throws IOException {
initialize();
}
private void initialize() throws IOException {
Square x = new Square("images\\black-X.png", "images\\blue-X.png", "x");
Square o = new Square("images\\black-O.png", "images\\blue-O.png", "o");
Square sq = new Square("images\\black-sq.png", "images\\blue-sq.png", "sq");
Square tri = new Square("images\\black-tri.png", "images\\blue-tri.png", "tri");
setLayout(new GridLayout(2, 2));
add(x);
add(o);
add(sq);
add(tri);
}
}
public class ClickListener extends MouseAdapter {
private Square ob;
public ClickListener(Square newSquare) {
ob = newSquare;
}
public void mouseClicked(MouseEvent e) {
ob.changePic();
}
}
public class Square extends JLabel {
String name;
private BufferedImage myPic1, myPic2;
public Square(String pic1, String pic2, String name) throws IOException {
this.name = name;
myPic1 = ImageIO.read(new File(pic1));
myPic2 = ImageIO.read(new File(pic2));
setIcon(new ImageIcon(myPic1));
addMouseListener(new ClickListener(this));
}
public String getName() {
return this.name;
}
public void changePic() {
setIcon(new ImageIcon(myPic2));
}
}
}