[英]Java Swing button disappear
I am trying to make an invisible button where the painted button is, but when I try to add the button, it disappear almost every time I run the program and when its visible it goes invisible on resize. 我试图在绘制的按钮所在的位置创建一个不可见的按钮,但是当我尝试添加该按钮时,几乎在每次运行该程序时,该按钮都会消失,并且当它可见时,它在调整大小时不可见。 Please help me, whats wrong?
请帮我,怎么了?
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
public class Main extends JFrame
{
public static final int VERSION = 1;
private static final long serialVersionUID = 1L;
private Image img;
private boolean hasMouseListener = false;
private Image bgImage;
public static int ii;
public static int jj;
public Main() throws IOException
{
super("Unigin Alpha 1.0.0"); //Set title
ii = this.getWidth();
jj = this.getHeight();
setBackground(Color.WHITE);
//loginForm1 = new LoginForm(this);
JPanel localJPanel = new JPanel();
//localJPanel.setLayout(null);
setVisible(true);
setTitle("Unigin");
setDefaultCloseOperation(EXIT_ON_CLOSE);
localJPanel.setPreferredSize(new Dimension(854, 480));
setLayout(new FlowLayout());
add(localJPanel, "Center");
//-------------------------------------------------------------------------
JButton bb = new JButton("HEEL");
localJPanel.add(bb, "CENTER");
//bb.setLocation(getWidth()/2-76-8, getHeight()/2); Doesn't work!
//i / 2 - 76 - 8, j / 2, 76, 20
pack();
setLocationRelativeTo(null);
try
{
setIconImage(ImageIO.read(Main.class.getResource("favicon.png")));
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
super.paint(getGraphics());
}
public void paint(Graphics paramGraphics)
{
try {
bgImage = ImageIO.read(Main.class.getResource("wool_red.png")).getScaledInstance(32, 32, 16);
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
int i = getWidth() / 2;
int j = getHeight() / 2;
if ((img == null) || (img.getWidth(null) != i) || (img.getHeight(null) != j)) {
img = createVolatileImage(i, j);
}
Graphics localGraphics = img.getGraphics();
for (int k = 0; k <= i / 32; k++)
for (int m = 0; m <= j / 32; m++)
localGraphics.drawImage(bgImage, k * 32, m * 32, null);
String str;
FontMetrics localFontMetrics;
if (true) {
if (!hasMouseListener) {
hasMouseListener = true;
//addMouseListener(this);
}
localGraphics.setColor(Color.WHITE);
str = "Bukkit Unigin";
localGraphics.setFont(new Font(null, 1, 20));
localFontMetrics = localGraphics.getFontMetrics();
localGraphics.drawString(str, i / 2 - localFontMetrics.stringWidth(str) / 2, j / 2 - localFontMetrics.getHeight() * 2);
localGraphics.setColor(Color.LIGHT_GRAY);
localGraphics.setFont(new Font(null, 0, 12));
localFontMetrics = localGraphics.getFontMetrics();
localGraphics.setColor(Color.LIGHT_GRAY);
localGraphics.fill3DRect(i / 2 - 76 - 8, j / 2, 76, 20, true);
localGraphics.fill3DRect(i / 2 + 8, j / 2, 76, 20, true);
//localGraphics.fill3DRect(x,y,width,height,true);
localGraphics.setColor(Color.WHITE);
str = "What do you want to do?";
localGraphics.drawString(str, i / 2 - localFontMetrics.stringWidth(str) / 2, j / 2 - 8);
localGraphics.setColor(Color.BLACK);
str = "New plugin";
localGraphics.drawString(str, i / 2 - 56 - 18 - localFontMetrics.stringWidth(str) / 2 + 28, j / 2 + 14);
str = "Load plugin";
localGraphics.drawString(str, i / 2 + 18 - localFontMetrics.stringWidth(str) / 2 + 28, j / 2 + 14);
}
localGraphics.dispose();
paramGraphics.drawImage(img, 0, 0, i * 2, j * 2, null);
}
public static void main(String[] args) throws IOException {
new Main();
}
}
The painting will disappear when you resize the frame because you aren't overriding the paintComponent
of a JComponent
you have a method named paint that runs once when called by the constructor. 当您调整框架的大小时,绘画将消失,因为您没有覆盖
JComponent
的paintComponent
,而是拥有一个名为paint的方法,该方法在构造函数调用时运行一次。
Instead break out your application into separate classes that each handle less responsibility. 而是将您的应用程序分为几个单独的类,每个类的责任较少。 One of which needs to override paintComponent() to actually draw the button.
其中之一需要重写paintComponent()才能真正绘制按钮。
Follow the Swing Tutorial for custom painting: http://docs.oracle.com/javase/tutorial/uiswing/painting/ 遵循Swing教程进行自定义绘画: http : //docs.oracle.com/javase/tutorial/uiswing/painting/
If you want to make an invisible JButton. 如果要制作一个不可见的JButton。
JButton invisibleButton = new JButton(){
@Override
protected void paintComponent(Graphics g){};
};
Remove super.paint(getGraphics());
删除
super.paint(getGraphics());
from constructor. 来自构造函数。
Reason: You should never do it. 原因:绝对不要这样做。 Use of repaint() is recommended although none is needed in this case.
建议使用repaint(),尽管在这种情况下不需要。
Call super.paint(g)
at the end of overridden paint method. 在覆盖的paint方法的末尾调用
super.paint(g)
。
Reason: This method is responsible for drawing children (Your button in this case). 原因:此方法负责绘制子项(在这种情况下为“按钮”)。 Button won't appear if you don't call it every time the frame is painted.
如果您在每次绘制框架时都不调用按钮,则按钮不会出现。
Call setBackGround(new java.awt.Color(0, 0, 0, 0));
调用
setBackGround(new java.awt.Color(0, 0, 0, 0));
in the constructor. 在构造函数中。
Reason: If you don't do this, the super.paint(g);
原因:如果不这样做,则
super.paint(g);
would erase everything you painted manually. 将删除您手动绘制的所有内容。
Personally I'd suggest using a JPanel for custom painting. 我个人建议使用JPanel进行自定义绘画。 It's painting mechanism is much cleaner (Separate paintComponent, paintBorder, paintChildren methods).
它的绘制机制更加简洁(单独的paintComponent,paintBorder,paintChildren方法)。
Good luck. 祝好运。
getGraphics
, it unreliable and this is not how custom painting is done getGraphics
,它不可靠,这不是完成自定义绘制的方式 paint
yourself, ever. paint
。 You are not responsible for performing painting operations, that's the responsibility of the RepaintManager
RepaintManager
的责任 super.paintXxx
when overriding paint methods. super.paintXxx
。 The painting process is a complex series of chained method calls which work together to generate the output. paint
of top level containers, top level containers are a complex series of components, overriding paint
can easily break this design as you have done here. paint
,顶层容器是一系列复杂的组件,覆盖paint
很容易破坏此设计,就像您在此处所做的那样。 They are also not double buffered paintXxx
method or performing any time consuming operations. paintXxx
方法中加载资源或执行任何耗时的操作。 Paint operations are intended to return quickly. Basically, by breaking the paint chain, you've prevented the paint process from being able to render the child components of the frame. 基本上,通过断开绘制链,可以防止绘制过程能够渲染框架的子组件。 You would run into issues even if you did call
super.paint
, as you would either paint over the top of what was previously painted or the paint process would clear what you painted before it...(not to mention that JFrame
has at least three layers of other containers sitting on top of it before you even add anything to it) 即使您确实调用了
super.paint
,您也会遇到问题,因为您将在先前绘制的内容之上绘制,或者绘制过程将清除您之前绘制的内容...(更不用说JFrame
至少具有三层其他容器位于其上,甚至没有添加任何东西)
Start by separating your program logic. 首先分离您的程序逻辑。 Focus on the needs of you "image", rendering to a custom component, extending from something like
JPanel
, but overriding it's paintComponent
method. 专注于您的“图像”需求,将其呈现给自定义组件,从诸如
JPanel
东西扩展而来,但是覆盖它的paintComponent
方法。
Add this to your frame (may as the content pane). 将此添加到您的框架(可能作为内容窗格)。 Add your other controls to it.
向其添加其他控件。
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details about how painting works and How to use root panes to understand the complex nature of top level containers in Swing 查看有关在AWT和Swing中执行自定义绘画和绘画的内容,以了解有关绘画工作原理以及如何使用根窗格来了解Swing中顶级容器的复杂性的更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.