3 回答

TA貢獻1805條經驗 獲得超9個贊
如果您仔細觀察,當您將鼠標懸停在它們應該出現的位置時,您會看到按鈕彈出。
這意味著您有 ZOorder 問題。ZOrder 是組件在 z 軸上彼此堆疊時繪制的順序。
Swing 以組件添加到面板的相反順序繪制組件,因此最后添加的組件首先被繪制。所以聽起來你有多個面板堆疊在一起,你添加的最后一個面板包含按鈕,但它首先被繪制,所以所有其他面板都在它上面繪制。
當鼠標移到按鈕上時,按鈕需要重新繪制自身以顯示按鈕的滾動效果,因此按鈕暫時被繪制在頂部,直到重新建立正確的 ZOrder 時父面板的下一次重新繪制。
我對您的程序結構了解得不夠多,但我會質疑為什么您將一堆面板堆疊在一起。您只需要一個帶有自定義繪畫的面板,然后將按鈕放置在該面板上。

TA貢獻1780條經驗 獲得超4個贊
您的主要問題就在這里...
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));
添加回答
舉報