Java swing JComponent "size"

3
我正在做一个项目,需要一些自定义的swing组件。到目前为止,我已经用一系列图像制作了一个新的按钮(Java Metal外观与我的UI完全不匹配)。我在这个新组件上实现了MouseListener,这就是我的问题所在。我的小部件在悬停、点击等时改变图像,但我的MouseListener会捕捉到鼠标进入整个GridLayout容器而不是进入图像。因此,当图像大小为200*100,周围容器大小约为400*200时,即使在其空白区域上,mouseEntered方法也会在进入该GridLayout部分时触发。我怎样才能使它只在我悬停在图片上时触发?我已尝试设置大小、边界和其他属性,但都无济于事。

编辑: 这是我的问题演示。如您所见(有点难看出来,颜色非常相似),右下角的按钮只要进入GridlLayout的那个区域就被突出显示了。我只希望它在我实际悬停在图像上方时被突出显示,而不是在GridLayout部分。

alt text

我不会添加MouseListener方法,因为它们只涉及切换显示的图像。

public customWidget()
{
    this.setLayout(new FlowLayout());
    try {
        imageDef=ImageIO.read(new File("/home/x101/Desktop/buttonDef.png"));
        imageClick=ImageIO.read(new File("/home/x101/Desktop/buttonClick.png"));
        imageHover=ImageIO.read(new File("/home/x101/Desktop/buttonHover.png"));
        current=imageDef;
    } catch (IOException e) 
    {

        e.printStackTrace();
    }
    this.addMouseListener(this);
}

protected void paintComponent(Graphics g)
{
    super.paintComponents(g);
    g.drawImage(current, 0, 0, current.getWidth(), current.getHeight(), null);

}

编辑:添加了代码部分


请提供一个自包含的代码示例,这样可以更容易地看到您要做什么,也更容易找到问题。 - Steve McLeod
'customWidget'的超类是什么?另外,你的'GridLayout容器'在哪里设置? - robert_x44
customWidget继承自JComponent。GridLayout是在我用来测试小部件的测试程序中设置的。将发布一张图片进行演示。 - Alex
3个回答

8
作为替代方案,考虑使用 按钮 API,其中包括方法 setRolloverIcon(),“使按钮在光标经过时显示指定的图标”。
附录:例如,
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ButtonIconTest {

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }

    private static void createAndShowGui() {
        String base = "http://download.oracle.com/"
            + "javase/tutorial/uiswing/examples/components/"
            + "RadioButtonDemoProject/src/components/images/";
        ImageIcon dog = null;
        ImageIcon pig = null;
        try {
            dog = new ImageIcon(new URL(base + "Dog.gif"));
            pig = new ImageIcon(new URL(base + "Pig.gif"));
        } catch (MalformedURLException ex) {
            ex.printStackTrace(System.err);
            return;
        }
        JFrame frame = new JFrame("Rollover Test");
        JPanel panel = new JPanel();
        panel.add(new JLabel(dog));
        panel.add(new JLabel(pig));

        JButton button = new JButton(dog);
        button.setRolloverIcon(pig);
        panel.add(button);

        frame.add(panel);

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

3
我假设你的图像仅包含4个“customWidget”对象(2x2网格)。
你的代码按照我的预期工作。你的MouseListener方法对于“customWidget”(而不是在“customWidget”中绘制的图像)响应MouseEvents,该组件大小占据图像的四分之一,因此当鼠标进入放大的区域时,它们将做出响应。实际上,错误出现在Test程序中,因为您允许自定义按钮小部件大于图像。
如果您想要一个提供类似于您的图像的测试程序,则应创建一个更大的网格(例如4x4),然后仅在每个其他网格节点中放置按钮。在空隙中放置一个空的组件即可。

你恰好和我想的一样。有没有一种布局管理器可以轻松地在屏幕上设置一个高度为110的部分,比如一个条形区域,而不是像网格布局和流式布局那样的比例关系? - Alex
“BoxLayout” 包括这样的不可见的填充组件:http://download.oracle.com/javase/tutorial/uiswing/layout/box.html#filler - trashgod
另外,如果您可以使用trashgod的方法,我强烈建议使用标准方法。 :) - robert_x44
MiGLayout 可以做任何事情(不是开玩笑,到目前为止我还没有想出 MiGLayout 做不到的事情。而且我的需求有时非常奇特...)! - brimborium

0

虽然我不会回答你的具体问题,但我希望这可以帮到你:

如果组件看起来不对劲,也许你应该重用 Swing 组件并编写自定义的 Look&Feel 或主题。

这肯定有助于确保应用程序的外观一致,并且至少你正在使用正确的工具来完成你想要完成的任务。

顺便提一下,要注意 Java 自带多个 Look&Feels,包括模仿本机操作系统主题的 Look&Feels。

请参阅:http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html


这是我知道的外观和感觉,但这是一个团队项目,我正在按照别人的设计工作,他们已经使用玻璃外观的按钮等使其变得闪亮。所以这是我决定采取的方向。无论如何,谢谢! - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接