[英]Linux Compton: How to Remove Window Shadow for Undecorated JFrame
[英]Undecorated JFrame shadow
如何為未修飾的 jframe 添加陰影?
根據我在網上找到的內容,您可以將 jframe 添加到另一個黑色半透明窗口以提供陰影效果。 或者以某種方式將這樣的東西應用於 JFrame:
Border loweredBorder = new EtchedBorder(EtchedBorder.LOWERED);
setBorder(loweredBorder);
無論哪種方式,我只想知道最好的方法,或者可能是一種完全不同的方式來獲得相同的效果,例如從另一個類而不是 jframe 擴展。 我是 Java 新手,所以我可能會走錯方向,所以任何建議都值得贊賞。
基本上,您需要制作一系列圖層。
JFrame
ShadowPanel
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
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 javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class ShadowWindow {
public static void main(String[] args) {
new ShadowWindow();
}
public ShadowWindow() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new ShadowPane());
JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel("Look ma, no hands"));
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ShadowPane extends JPanel {
public ShadowPane() {
setLayout(new BorderLayout());
setOpaque(false);
setBackground(Color.BLACK);
setBorder(new EmptyBorder(0, 0, 10, 10));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fillRect(10, 10, getWidth(), getHeight());
g2d.dispose();
}
}
}
瘋狂程序員,
frame.setBackground(new Color(0, 0, 0, 0));
如果你不使用也是沒用的:
frame.setOpacity(1.0f);
將默認關閉操作設置為 EXIT_ON_CLSE 是不好的,應用程序應該在兩個進程結束時自然關閉,所以 DISPOSE_ON_CLOSE 是正確的方法,保留另一個來“修復”錯誤。
frame.setContentPane(new ShadowPanel());
如果您還使用(以及之后),則無用:
frame.add(panel);
ShadowPanel 的構造函數應該以:
super(new GridBagLayout());
而不是:
setLayout(new GridBagLayout());
另外,使用 GridBagLayout 僅添加單個組件有點不成比例,不是嗎? GridLayout(1, 1) 甚至懶惰的 BorderLayout 怎么樣?
在每次調用首選大小時返回一個新維度(其中許多是由機器完成的,在大量操作期間,例如重新繪制等)非常昂貴。 您應該返回在構造函數或類中定義的變量。
為什么要覆蓋 getPreferredSize(),而不是 getBackground() 和 isOpaque() ?
GraphicsD 應該放在 try 塊內,以便在 finally 塊內處理它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.