我试图在绘制按钮的位置创建一个隐形按钮,但是当我尝试添加按钮时,它几乎每次运行程序时都会消失,当它可见时它会在调整大小时变得不可见。请帮帮我,怎么回事?
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();
}
}
答案 0 :(得分:0)
当您调整框架大小时,绘画将消失,因为您没有覆盖paintComponent
的{{1}},您有一个名为paint的方法,该方法在构造函数调用时运行一次。
而是将您的应用程序分解为各自处理较少责任的单独类。其中一个需要覆盖paintComponent()来实际绘制按钮。
按照Swing教程进行自定义绘画:http://docs.oracle.com/javase/tutorial/uiswing/painting/
答案 1 :(得分:0)
如果你想制作一个看不见的JButton。
JButton invisibleButton = new JButton(){
@Override
protected void paintComponent(Graphics g){};
};
答案 2 :(得分:0)
从构造函数中删除super.paint(getGraphics());
。
原因:你永远不应该这样做。建议使用repaint(),但在这种情况下不需要。
在重写的paint方法结束时调用super.paint(g)
。
原因:此方法负责绘制孩子(在这种情况下为您的按钮)。如果每次绘制画面时都不调用按钮,则不会出现按钮。
在构造函数中调用setBackGround(new java.awt.Color(0, 0, 0, 0));
。
原因:如果您不这样做,super.paint(g);
会删除您手动绘制的所有内容。
我个人建议使用JPanel进行自定义绘画。它的绘画机制更清晰(Separate paintComponent,paintBorder,paintChildren方法)。
祝你好运。答案 3 :(得分:0)
getGraphics
,它不可靠,这不是自定义绘画的完成方式paint
。您不负责执行绘画操作,这是RepaintManager
super.paintXxx
。绘制过程是一系列复杂的链式方法调用,它们协同工作以生成输出。您应该避免覆盖paint
顶级容器,顶级容器是一系列复杂的组件,覆盖paint
可以轻松破坏此设计,就像您在此处所做的那样。它们也不是双缓冲的paintXxx
方法中加载资源或执行任何耗时的操作。油漆操作旨在快速返回。如果不这样做会显着减缓重绘过程。基本上,通过打破画颜链,您已经阻止了绘制过程能够渲染框架的子组件。即使您调用了super.paint
,也会遇到问题,因为您要么绘制之前绘制的顶部,或者绘制过程会清除您之前绘制的内容......(更不用说{{ 1}}在你添加任何东西之前至少有三层其他容器坐在它上面)
首先分离你的程序逻辑。专注于“图像”的需求,渲染到自定义组件,从JFrame
扩展,但覆盖它的JPanel
方法。
将此添加到您的框架(可能作为内容窗格)。添加其他控件。
查看Performing Custom Painting和Painting in AWT and Swing了解有关绘画如何工作的更多详细信息,并How to use root panes了解Swing中顶级容器的复杂性质