3 回答
TA贡献1805条经验 获得超9个赞
如果您仔细观察,当您将鼠标悬停在它们应该出现的位置时,您会看到按钮弹出。
这意味着您有 ZOorder 问题。ZOrder 是组件在 z 轴上彼此堆叠时绘制的顺序。
Swing 以组件添加到面板的相反顺序绘制组件,因此最后添加的组件首先被绘制。所以听起来你有多个面板堆叠在一起,你添加的最后一个面板包含按钮,但它首先被绘制,所以所有其他面板都在它上面绘制。
当鼠标移到按钮上时,按钮需要重新绘制自身以显示按钮的滚动效果,因此按钮暂时被绘制在顶部,直到重新建立正确的 ZOrder 时父面板的下一次重新绘制。
我对您的程序结构了解得不够多,但我会质疑为什么您将一堆面板堆叠在一起。您只需要一个带有自定义绘画的面板,然后将按钮放置在该面板上。
TA贡献1780条经验 获得超3个赞
您的主要问题就在这里...
Graphics2D g2d = (Graphics2D) g;
g2d.translate(getWidth() / 2, getHeight() / 2);
AffineTransform at = AffineTransform.getTranslateInstance(0, 0);
Graphics传递给组件的上下文是共享资源,它会传递给在绘制周期中绘制的所有组件,这意味着当您更改原点和旋转等内容时,它会影响在它之后绘制的所有组件。
相反,您应该Graphics在应用更改之前创建状态的副本,这会保持原始状态不变
Graphics2D g2d = (Graphics2D) g.create();
g2d.translate(getWidth() / 2, getHeight() / 2);
AffineTransform at = AffineTransform.getTranslateInstance(0, 0);
//...
g2d.dispose();
你的第二个错误是...
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
update();
}
}, 0, (long) Math.round(motion.getFrameTime() * 1000));
Swing 不是线程安全的,更新 UI 或 UI 所依赖的状态可能会产生意外且难以诊断的结果。
在这种情况下,您有两种选择,根据您的需要使用 SwingTimer或 a SwingWorker。
查看Swing中的并发以获取更多详细信息
另一个问题是at.rotate(Math.toRadians(90), Math.toRadians(90), Math.toRadians(90));。这根本没有意义。
该文档的状态
公共无效旋转(双θ,
双锚x,
双锚)
将此变换与围绕锚点旋转坐标的变换连接起来。这个操作相当于平移坐标,使锚点在原点(S1),然后绕新原点(S2)旋转,最后平移,使中间原点恢复到原锚点的坐标(S3)。此操作等效于以下调用序列:
translate(anchorx, anchory); // S3: final translation
rotate(theta); // S2: rotate around anchor
translate(-anchorx, -anchory); // S1: translate anchor to origin Rotating by a positive angle theta rotates points on the
正 X 轴朝向正 Y 轴。另请注意上述处理 90 度旋转的讨论。
参数:
theta- 以弧度为单位
anchorx的旋转角度
anchory-旋转锚点的 X 坐标 - 旋转锚点的 Y 坐标
这就是说,第二个和第三个参数实际上是旋转发生的点。在你的情况下at.rotate(Math.toRadians(90), 0, 0);可能是你真正想要的。
使用 Graphics#create
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private double angle;
public TestPane() {
setLayout(new GridBagLayout());
for (int index = 0; index < 5; index++) {
add(new JButton("Here"));
}
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
angle += 0.01;
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
//Graphics2D g2d = (Graphics2D) g;
g2d.translate(getWidth() / 2, getHeight() / 2);
AffineTransform at = AffineTransform.getTranslateInstance(0, 0);
at.rotate(Math.toRadians(90), 0, 0);
g2d.drawRect(-50, -50, 100, 100);
g2d.setColor(Color.RED);
g2d.rotate(angle, 0, 0);
g2d.drawRect(-100, -100, 200, 200);
g2d.dispose();
}
}
}
不使用 Graphics#create
哦,哦,我的按钮在哪里 - 根据您对Graphics
上下文所做的更改,可能围绕容器的中心点旋转了 90 度,所以现在它们可能不在屏幕上
TA贡献1982条经验 获得超2个赞
我已经转移到 JLayeredPane 以获得我正在寻找的效果。我可以点击顶层并拖动底层。
LayerUI backgroundUI = new WallpaperLayerUI();
jlayer = new JLayer<JPanel>(panel, backgroundUI);
LayerUI controlsUI = new LayerUI();
JPanel controlPanel = new JPanel();
MigLayout layout = new MigLayout(
"debug, insets 10, gap 10, wrap", // Layout Constraints
"[fill,grow][fill,grow][fill,grow]", // Column constraints with default align
"[fill,grow][fill,grow][fill,grow]");
controlPanel.setLayout(layout);
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
controlPanel.add(new JButton("here"));
jlayer2 = new JLayer<JPanel>(controlPanel, controlsUI);
panel.addMouseListener(this);
panel.addMouseMotionListener(this);
panel.addMouseWheelListener(this);
finalPanel = new JLayeredPane();
finalPanel.setPreferredSize(new Dimension(300, 310));
//finalPanel.setLayout(null);
jlayer.setBounds(0, 0, (808-40)/3, (608-40)/3);
jlayer2.setBounds(0, 0, (808-80)/3, (608-80)/3);
controlPanel.setBackground(new Color(0,0,0,0));
finalPanel.add(jlayer, new Integer(0));
finalPanel.add(jlayer2 ,new Integer(1));
添加回答
举报