3 回答

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

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超4個(gè)贊
您的主要問題就在這里...
Graphics2D g2d = (Graphics2D) g;
g2d.translate(getWidth() / 2, getHeight() / 2);
AffineTransform at = AffineTransform.getTranslateInstance(0, 0);
Graphics傳遞給組件的上下文是共享資源,它會(huì)傳遞給在繪制周期中繪制的所有組件,這意味著當(dāng)您更改原點(diǎn)和旋轉(zhuǎn)等內(nèi)容時(shí),它會(huì)影響在它之后繪制的所有組件。
相反,您應(yīng)該Graphics在應(yīng)用更改之前創(chuàng)建狀態(tài)的副本,這會(huì)保持原始狀態(tài)不變
Graphics2D g2d = (Graphics2D) g.create();
g2d.translate(getWidth() / 2, getHeight() / 2);
AffineTransform at = AffineTransform.getTranslateInstance(0, 0);
//...
g2d.dispose();
你的第二個(gè)錯(cuò)誤是...
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
update();
}
}, 0, (long) Math.round(motion.getFrameTime() * 1000));
Swing 不是線程安全的,更新 UI 或 UI 所依賴的狀態(tài)可能會(huì)產(chǎn)生意外且難以診斷的結(jié)果。
在這種情況下,您有兩種選擇,根據(jù)您的需要使用 SwingTimer或 a SwingWorker。
查看Swing中的并發(fā)以獲取更多詳細(xì)信息
另一個(gè)問題是at.rotate(Math.toRadians(90), Math.toRadians(90), Math.toRadians(90));。這根本沒有意義。
該文檔的狀態(tài)
公共無效旋轉(zhuǎn)(雙θ,
雙錨x,
雙錨)
將此變換與圍繞錨點(diǎn)旋轉(zhuǎn)坐標(biāo)的變換連接起來。這個(gè)操作相當(dāng)于平移坐標(biāo),使錨點(diǎn)在原點(diǎn)(S1),然后繞新原點(diǎn)(S2)旋轉(zhuǎn),最后平移,使中間原點(diǎn)恢復(fù)到原錨點(diǎn)的坐標(biāo)(S3)。此操作等效于以下調(diào)用序列:
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 軸。另請(qǐng)注意上述處理 90 度旋轉(zhuǎn)的討論。
參數(shù):
theta- 以弧度為單位
anchorx的旋轉(zhuǎn)角度
anchory-旋轉(zhuǎn)錨點(diǎn)的 X 坐標(biāo) - 旋轉(zhuǎn)錨點(diǎn)的 Y 坐標(biāo)
這就是說,第二個(gè)和第三個(gè)參數(shù)實(shí)際上是旋轉(zhuǎn)發(fā)生的點(diǎn)。在你的情況下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
哦,哦,我的按鈕在哪里 - 根據(jù)您對(duì)Graphics
上下文所做的更改,可能圍繞容器的中心點(diǎn)旋轉(zhuǎn)了 90 度,所以現(xiàn)在它們可能不在屏幕上

TA貢獻(xiàn)1982條經(jīng)驗(yàn) 獲得超2個(gè)贊
我已經(jīng)轉(zhuǎn)移到 JLayeredPane 以獲得我正在尋找的效果。我可以點(diǎn)擊頂層并拖動(dòng)底層。
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));
添加回答
舉報(bào)