JPanel 失去焦点并且听众没有开火
JPanel losing focus and listeners aren't firing
所以在我的 window 中,我将 JFrame
设置为 undecorated(true)
并在顶部设置了我自己的自定义 header(带有关闭和最小化按钮)。我遇到的唯一问题是当您拖动此 'custom header' 时使 window 移动。整个 header 在 JPanel
中,然后添加到北侧的 JFrame
(BorderLayout.NORTH
)。我有一个 MouseListener
和 MouseMotionListener
添加到这个 JPanel
,但它不识别任何事件。我唯一可以假设的是我是如何弄清楚布局的。下面是 header 的代码,以及与之配套的视觉效果。
代码:
private void addHeader()
{
headPane = new JPanel();
headPane.setLayout(new BoxLayout(headPane, BoxLayout.LINE_AXIS));
buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 2));
buttonPane.setBackground(mouseLineColor);
headPane.setBackground(Color.GREEN);
Font buttonFont = new Font("", Font.PLAIN, 18);
minimize.setFocusable(false);
minimize.setPreferredSize(new Dimension(30, 20));
minimize.setMargin(new Insets(0, 0, 0, 0));
minimize.setOpaque(false);
minimize.setBorder(null);
minimize.setForeground(Color.WHITE);
minimize.setOpaque(true);
minimize.setFont(buttonFont);
minimize.setBackground(buttonColor);
quit.setFocusable(false);
quit.setPreferredSize(new Dimension(30, 20));
quit.setMargin(new Insets(0, 0, 0, 0));
quit.setOpaque(false);
quit.setBorder(null);
quit.setForeground(Color.WHITE);
quit.setOpaque(true);
quit.setFont(buttonFont);
quit.setBackground(buttonColor);
back.setFocusable(false);
back.setPreferredSize(new Dimension(30, 20));
back.setMargin(new Insets(0, 0, 0, 0));
back.setOpaque(false);
back.setBorder(null);
back.setForeground(Color.WHITE);
back.setOpaque(true);
back.setFont(buttonFont);
back.setBackground(buttonColor);
if(screen != GAME_MENU)
buttonPane.add(back);
else
buttonPane.remove(back);
buttonPane.add(minimize);
buttonPane.add(quit);
headTitle = new JLabel("Bouncy Ball Version " + VERSION);
headTitle.setBorder(new EmptyBorder(0, 5, 0, 0));
headTitle.setFont(new Font("", Font.BOLD, 14));
headTitle.setForeground(Color.BLACK);
headTitle.setBackground(Color.YELLOW);
headTitle.setOpaque(true);
headTitle.setFocusable(false);
headPane.setFocusable(false);
buttonPane.setFocusable(false);
buttonPane.setBackground(Color.RED);
headPane.add(headTitle);
headPane.add(Box.createHorizontalGlue());
headPane.add(buttonPane);
if(callOnce)
{
minimize.addActionListener(this);
quit.addActionListener(this);
back.addActionListener(this);
minimize.addMouseListener(this);
quit.addMouseListener(this);
back.addMouseListener(this);
headPane.addMouseListener(this);
headPane.addMouseMotionListener(this);
callOnce = false;
}
headPane.setPreferredSize(new Dimension(headPane.getPreferredSize().width, 24));
frame.add(headPane, BorderLayout.NORTH);
}
听众:
鼠标按下:
Object source = e.getSource();
if(source == headPane)
{
mouseX = e.getX();
mouseY = e.getY();
movingWindow = true;
}
鼠标拖动:
Object source = e.getSource();
if(source == headPane)
{
if(movingWindow)
{
int x = e.getXOnScreen();
int y = e.getYOnScreen();
frame.setLocation(x - mouseX, y - mouseY);
}
}
我还要补充一点,当我单击 headPane
时,JButton
也会停止工作。我不知道它为什么这样做,或者答案是否真的很简单,我只是愚蠢,但我尝试过的任何事情都没有奏效。
我是 Java 的新手,所以在此先感谢您的帮助。
我认为不需要 "callOnce" 变量。框架和添加到框架的组件应该只在创建 class 时创建一次。如果你不止一次调用"addHeader()"方法,那么我建议你有设计问题。
此外,您不应将 ActionListeners 添加到您的按钮两次。
The only problem I'm having is making the window move when you drag this 'custom header'.
查看 Moving Windows 的一般用途 class,它允许您拖动任何组件。通常,您会在面板内拖动组件。
但是,class还有一个功能,允许您通过拖动添加到window的组件在桌面上拖动window。
所以在我的 window 中,我将 JFrame
设置为 undecorated(true)
并在顶部设置了我自己的自定义 header(带有关闭和最小化按钮)。我遇到的唯一问题是当您拖动此 'custom header' 时使 window 移动。整个 header 在 JPanel
中,然后添加到北侧的 JFrame
(BorderLayout.NORTH
)。我有一个 MouseListener
和 MouseMotionListener
添加到这个 JPanel
,但它不识别任何事件。我唯一可以假设的是我是如何弄清楚布局的。下面是 header 的代码,以及与之配套的视觉效果。
代码:
private void addHeader()
{
headPane = new JPanel();
headPane.setLayout(new BoxLayout(headPane, BoxLayout.LINE_AXIS));
buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 2));
buttonPane.setBackground(mouseLineColor);
headPane.setBackground(Color.GREEN);
Font buttonFont = new Font("", Font.PLAIN, 18);
minimize.setFocusable(false);
minimize.setPreferredSize(new Dimension(30, 20));
minimize.setMargin(new Insets(0, 0, 0, 0));
minimize.setOpaque(false);
minimize.setBorder(null);
minimize.setForeground(Color.WHITE);
minimize.setOpaque(true);
minimize.setFont(buttonFont);
minimize.setBackground(buttonColor);
quit.setFocusable(false);
quit.setPreferredSize(new Dimension(30, 20));
quit.setMargin(new Insets(0, 0, 0, 0));
quit.setOpaque(false);
quit.setBorder(null);
quit.setForeground(Color.WHITE);
quit.setOpaque(true);
quit.setFont(buttonFont);
quit.setBackground(buttonColor);
back.setFocusable(false);
back.setPreferredSize(new Dimension(30, 20));
back.setMargin(new Insets(0, 0, 0, 0));
back.setOpaque(false);
back.setBorder(null);
back.setForeground(Color.WHITE);
back.setOpaque(true);
back.setFont(buttonFont);
back.setBackground(buttonColor);
if(screen != GAME_MENU)
buttonPane.add(back);
else
buttonPane.remove(back);
buttonPane.add(minimize);
buttonPane.add(quit);
headTitle = new JLabel("Bouncy Ball Version " + VERSION);
headTitle.setBorder(new EmptyBorder(0, 5, 0, 0));
headTitle.setFont(new Font("", Font.BOLD, 14));
headTitle.setForeground(Color.BLACK);
headTitle.setBackground(Color.YELLOW);
headTitle.setOpaque(true);
headTitle.setFocusable(false);
headPane.setFocusable(false);
buttonPane.setFocusable(false);
buttonPane.setBackground(Color.RED);
headPane.add(headTitle);
headPane.add(Box.createHorizontalGlue());
headPane.add(buttonPane);
if(callOnce)
{
minimize.addActionListener(this);
quit.addActionListener(this);
back.addActionListener(this);
minimize.addMouseListener(this);
quit.addMouseListener(this);
back.addMouseListener(this);
headPane.addMouseListener(this);
headPane.addMouseMotionListener(this);
callOnce = false;
}
headPane.setPreferredSize(new Dimension(headPane.getPreferredSize().width, 24));
frame.add(headPane, BorderLayout.NORTH);
}
听众:
鼠标按下:
Object source = e.getSource();
if(source == headPane)
{
mouseX = e.getX();
mouseY = e.getY();
movingWindow = true;
}
鼠标拖动:
Object source = e.getSource();
if(source == headPane)
{
if(movingWindow)
{
int x = e.getXOnScreen();
int y = e.getYOnScreen();
frame.setLocation(x - mouseX, y - mouseY);
}
}
我还要补充一点,当我单击 headPane
时,JButton
也会停止工作。我不知道它为什么这样做,或者答案是否真的很简单,我只是愚蠢,但我尝试过的任何事情都没有奏效。
我是 Java 的新手,所以在此先感谢您的帮助。
我认为不需要 "callOnce" 变量。框架和添加到框架的组件应该只在创建 class 时创建一次。如果你不止一次调用"addHeader()"方法,那么我建议你有设计问题。
此外,您不应将 ActionListeners 添加到您的按钮两次。
The only problem I'm having is making the window move when you drag this 'custom header'.
查看 Moving Windows 的一般用途 class,它允许您拖动任何组件。通常,您会在面板内拖动组件。
但是,class还有一个功能,允许您通过拖动添加到window的组件在桌面上拖动window。