Java:在动作侦听器中使用图形组件 [英] Java : using graphics component within an action listener
问题描述
我用Diferent JButtons制作了一个JFrame,我想从另一个类中获取图像.有任何想法吗?还是如何借鉴同一个班级但要采取的行动? 因为它不允许我做任何绘图...我的编译器总是给我错误消息
I've made a JFrame with Diferent JButtons and i'd like to get an image from another class. Any ideas? Or how draw on the same class but on the action performed? Because it doesnt let me to do any drawings...my complier always gives me error messages
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.*;
public class red extends JFrame {
public JButton b;
public JButton b1;
public JButton b2;
public JButton b3;
public JButton b4;
public static Image p;
public static Graphics g;
public red() throws IOException {
gui1 x = new gui1();
setTitle(" ");
setSize(1200,700);
setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
b= new JButton("click");
b1= new JButton();
b.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e0){
b1.setBounds(0, 0, 200, 200);
b.show(false);
add(x);
}
});
b.setBounds(0, 0, 100, 100);
add(b1);
add(b);
setVisible(true);
}
public static void main(String[] args) throws IOException {
red k = new red();
}
}
import java.awt.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class gui1 extends Canvas {
public static Image p;
public void paint(Graphics g){
g.drawImage(p, 700, 200, 100, 100, this);
}
{
try {
p= ImageIO.read(new File("Lighthouse.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
推荐答案
Ph!我在您的代码中看到了很多错误(即使我更正了编译错误):
Phew! I see A LOT of errors in your code (even after I corrected the compilation errors):
-
您没有遵循 Java命名约定:
类名应为名词,大小写混合,每个内部单词的首字母应大写
Class names should be nouns, in mixed case with the first letter of each internal word capitalized
red
是名词,但应更具描述性且大写. gui1
while red
is a noun it should be more descriptive and be capitalized. The same goes for gui1
您要扩展JFrame
,用简单的英语说:red
是 JFrame
,您应该避免这种情况,并基于JPanel
创建GUI改为使用s ...参见使用扩展的Java Swing JFrame vs callint在类内部
You're extending JFrame
which in plain english would say: red
is a JFrame
, you should really avoid this and create your GUI based on JPanel
s instead... see Java Swing using extends JFrame vs callint it inside of class
您正在设置大小(对于正在使用的JButton
大小,这是一个非常大的窗口),而不是使用
You're setting size (a REAAAAAAALLY big one window for the JButton
sizes you're using), instead use pack()
您正在使用null-layout
,虽然像素完美的GUI似乎是为Swing新手创建复杂GUI的最简单方法,但使用它们越多,与此相关的问题就越多.将来,它们很难维护并导致随机问题,它们无法调整大小等.请阅读为什么不愿在Swing中使用空布局?以获取有关为什么应避免使用它以及为什么应更改GUI以与空边框可在组件之间留出额外的间距.
You're using null-layout
, while pixel-perfect GUIs might seem like the easiest way to create complex GUIs for Swing newbies, the more you use them the more problems related to this you'll find in the future, they are hard to maintain and cause random problems, they don't resize, etc. Please read Null layout is evil and Why is it frowned upon to use a null layout in Swing? for more information about why you should avoid its use and why you should change your GUI to work with Layout Managers along with Empty Borders for extra spacing between components.
您正在使用不推荐使用的方法 JFrame#show()
,您应该使用
You're making use of a deprecated method JFrame#show()
you should be using JFrame#setVisible(...)
instead.
与第4点相关,您不应调用setBounds(...)
方法,而应将计算结果发送给布局管理器.
Related to point #4, you shouldn't be calling setBounds(...)
method, but let that calculations to the layout managers.
您没有将程序放在事件上调度线程(EDT),Swing不是线程安全的,您可以通过如下更改main()
方法来解决此问题:
You're not placing your program on the Event Dispatch Thread (EDT), Swing is not thread safe, you can fix this by changing your main()
method as follows:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//Your constructor here
}
});
}
您正在混合使用AWT和Swing组件,而不是使用AWT的 Canvas
使用Swing的
You're mixing AWT and Swing components, instead of using AWT's Canvas
use Swing's JPanel
which has more functionality and support.
将图像打包到JAR文件中后,它们将成为嵌入式资源,因此明智的做法是开始将它们视为已经存在,而不是像 embedded-resource 标签.
Images will become embedded resources once they're packaged in a JAR file, so it's wise to start treating them as if they already were, not as external files as shown in the embedded-resource tag.
一旦从Canvas
更改为JPanel
,则应覆盖其 paint(...)
并将其称为super.paintComponent(g)
方法作为第一行,也不要忘记添加@Overrides
批注.请参见关于Swing自定义绘画的教程.
Once you change from Canvas
to JPanel
you should override its paintComponent(...)
method and not paint(...)
and call it's super.paintComponent(g)
method as the first line, also don't forget to add the @Overrides
annotation. See the tutorial on Swing custom painting.
You're abusing the use of static
keyword, see how does the static keyword works?
看到上述所有错误后,我建议您返回并了解基础知识语言,然后再开始使用图形化环境,这只会给您的学习增加更多难度.
After seeing all the above errors I recommend you to go back and Learn the basics of the language before starting with a graphical environment which will only add more difficulty to your learning.
据我了解,您希望在单击按钮时绘制图像,如果是这种情况,则可以将图像包装在JLabel
中,并将该JLabel
添加到JPanel
中,然后添加到JPanel
中.父JPanel
,后来又添加到了JFrame
:
From what I understand you want to draw an image on a button click, if that's the case then you can wrap your image in a JLabel
and add that JLabel
to a JPanel
which then is added to a parent JPanel
which is later added to the JFrame
:
如您在上面的GIF中所看到的,用户按下按钮后,该图标就会显示.
As you can see in the GIF above, the icon is displayed after user presses the button.
很明显,可以通过组合布局管理器和空白边框来使GUI更具吸引力".
Obviously this can be improved for the GUI to be more "attractive" with combinations of layout managers and empty borders as stated before.
这是通过以下代码完成的:
This was done with the following code:
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ImageDrawingFromOneClassToAnother {
private JFrame frame;
private JPanel pane;
private JPanel leftPane;
private JPanel rightPane;
private ImageIcon icon;
private JButton button;
private JLabel label;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ImageDrawingFromOneClassToAnother().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
icon = new ImageIcon(this.getClass().getResource("king.png")); //Read images as if they were already embedded resources
button = new JButton("Draw image");
label = new JLabel(""); //Create an empty label
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.setIcon(icon); //On button click, we set the icon for the empty label
}
});
pane = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200); //Set a size for the main panel
}
};
pane.setLayout(new GridLayout(1, 2)); //The main panel
leftPane = new JPanel(); //The button panel
leftPane.setLayout(new BoxLayout(leftPane, BoxLayout.PAGE_AXIS));
leftPane.add(button);
rightPane = new JPanel(); //The panel where the image will be drawn
rightPane.add(label);
//We add both (button and image) panels to the main panel
pane.add(leftPane);
pane.add(rightPane);
frame.add(pane); //Add the main panel to the frame
frame.pack(); //Calculate its preferred size
frame.setVisible(true); //Set it to be visible
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
这篇关于Java:在动作侦听器中使用图形组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!