使 JButton 重叠

发布于 2024-10-05 05:16:26 字数 1587 浏览 0 评论 0原文

我正在 Java Swing 中创建一个虚拟钢琴类型程序。我现在的钢琴键区域是一个带有水平 BoxLayout 的 JPanel,其中包含白色 JButton 作为白键。我还想添加黑键,并让它们与白键重叠。

我尝试过两种不同的方法。一种是使用 OverlayLayout。不幸的是,关于 OverlayLayout 管理器的在线文档并不多,而且 NetBeans GUI 构建器中也没有该文档。我不知道如何让它发挥作用。我尝试的第二件事是使用 JLayeredPanes。即使在 Netbeans 中搞乱了它之后,我似乎也无法弄清楚这一点。

所以我认为我的问题很简单。如果有的话,将 JButton 添加到其他 JButton 之上的最佳方法是什么?或者也许还有使用 JButtons 作为钢琴键的替代方法?

编辑

我结合了 aioobe 和 dacwe 的代码来获得我想要的结果。我基本上使用了 dacwe 的 z 排序和 aioobe 的基本尺寸(稍微放大了一点)以及 mod 7 部分。我还添加了一些变量以使事情更加清晰。这就是我现在所拥有的。

import javax.swing.*;
import java.awt.Color;

public class Test2 {

public static void main(String[] args) {

    JFrame frame = new JFrame("Test");

    JLayeredPane panel = new JLayeredPane();
    frame.add(panel);

    int maxKeys = 8;

    int width = 60;
    int height = 240;

    for (int i = 0; i < maxKeys; i++) {
        JButton b = new JButton();
        b.setBackground(Color.WHITE);
        b.setLocation(i * width, 0);
        b.setSize(width, height);

        panel.add(b, 0, -1);
    }

    int width2 = 48;
    int height2 = 140;
    for (int i = 0; i < maxKeys; i++) {
        int j = i % 7;
        if (j == 2 || j == 6)
            continue;

        JButton b = new JButton();
        b.setBackground(Color.BLACK);
        b.setLocation(i*(width) + (width2*3/4), 0);
        b.setSize(width2, height2);

        panel.add(b, 1, -1);
    }

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(500,280);
    frame.setVisible(true);
    }
}

谢谢你们!现在我需要以某种方式将侦听器和文本附加到这些按钮。

I'm creating a virtual piano type program in Java Swing. My area for the piano keys right now is a JPanel with a horizontal BoxLayout containing white JButtons as white keys. I want to add black keys as well, and have them overlap the white keys.

There are two different approaches I've tried. One is using the OverlayLayout. Unfortunately there isn't much documentation online for the OverlayLayout manager, and it's not available in the NetBeans GUI builder. I don't have a clue how to make it work. The second thing I've tried is using JLayeredPanes. I can't seem to figure that one out either, even after messing with it in Netbeans.

So I think my question is pretty simple. What is the best approach, if there is one, to add JButtons on top of other JButtons? Or maybe there is an alternative to using JButtons for piano keys?

EDIT

I've combined aioobe's and dacwe's code to get the result I wanted. I basically used dacwe's z-ordering with aioobe's basic dimensions (scaled up a bit) and the mod 7 part too. I also added some variables to make things more clear. This is what I have now.

import javax.swing.*;
import java.awt.Color;

public class Test2 {

public static void main(String[] args) {

    JFrame frame = new JFrame("Test");

    JLayeredPane panel = new JLayeredPane();
    frame.add(panel);

    int maxKeys = 8;

    int width = 60;
    int height = 240;

    for (int i = 0; i < maxKeys; i++) {
        JButton b = new JButton();
        b.setBackground(Color.WHITE);
        b.setLocation(i * width, 0);
        b.setSize(width, height);

        panel.add(b, 0, -1);
    }

    int width2 = 48;
    int height2 = 140;
    for (int i = 0; i < maxKeys; i++) {
        int j = i % 7;
        if (j == 2 || j == 6)
            continue;

        JButton b = new JButton();
        b.setBackground(Color.BLACK);
        b.setLocation(i*(width) + (width2*3/4), 0);
        b.setSize(width2, height2);

        panel.add(b, 1, -1);
    }

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(500,280);
    frame.setVisible(true);
    }
}

Thanks guys! Now I need to attach the listener and text to these buttons somehow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

时光无声 2024-10-12 05:16:41

在此帖子中查看 Darryl 的解决方案(最后回复)。它变得很棘手,并使用“Button”作为黑色按钮,因此它绘制在白色“JButton”之上。这可能在允许混合 AWT 和 Swing 组件的 JDK 新版本中不起作用。

然而,巧妙的是,点击按键时实际上会发出声音。

Check out Darryl's solution (the last reply) in this posting. It gets tricky and uses a "Button" as the black button so it paints on top of the white "JButton". This probably won't work in new versions of the JDK that allow AWT and Swing components to be mixed.

However, the neat part is that the keys actually produce a sound when clicked.

蓝眼睛不忧郁 2024-10-12 05:16:40

我在 Swing 中做过几个游戏,我发现不使用布局管理器或自己制作布局管理器会更容易。例如,我有一个纸牌游戏和一个自定义布局管理器,它可以查看纸牌的播放位置并根据该纸牌和当前面板大小来定位它。

I've done a couple games in Swing, and I find it's easier just not to use a layout manager or make your own. For example I have a card game and a custom layout manager that looks at where the card has been played and positions it based on that and the current panel size.

半岛未凉 2024-10-12 05:16:38

GridBag 布局确实允许小部件重叠;您可以使用重叠的跨度来构造您想要的布局。但是,是的,编写自己的布局管理器会更好。

GridBag layout does allow widget overlapping; You could use overlapping spans to construct the layout You want. But yes, writing own layout manager wold be nicer.

旧伤慢歌 2024-10-12 05:16:37

除了编写自己的布局管理器之外,您还可以使用 null LayoutManager(即,无自动布局管理)并手动定位键。然后在容器上使用 setComponentZOrder 以确保黑键出现在白键上方。

Apart from writing your own layout manager, you could just use a null LayoutManager (that is, no automatic layout management) and position the keys manually. Then use setComponentZOrder on the container to make sure the black keys appear above the white ones.

泅人 2024-10-12 05:16:35

这是分层窗格的示例(它按您的预期工作):

public static void main(String[] args) {

    JFrame frame = new JFrame("Test");

    JLayeredPane panel = new JLayeredPane();
    frame.add(panel);


    for (int i = 0; i < 8; i++) {
        JButton b = new JButton();
        b.setBackground(Color.WHITE);
        b.setLocation(i * 20, 0);
        b.setSize(20, 100);

        panel.add(b, 0, -1);
    }

    for (int i = 0; i < 4; i++) {
        JButton b = new JButton();
        b.setBackground(Color.BLACK);
        b.setLocation(10 + i * 40, 0);
        b.setSize(20, 70);

        panel.add(b, 1, -1);
    }

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 300);
    frame.setVisible(true);
}

但是,您需要以正确的顺序布置钢琴键 (:)) :

替代文字

This is an example of layeredpane (it works as you expect):

public static void main(String[] args) {

    JFrame frame = new JFrame("Test");

    JLayeredPane panel = new JLayeredPane();
    frame.add(panel);


    for (int i = 0; i < 8; i++) {
        JButton b = new JButton();
        b.setBackground(Color.WHITE);
        b.setLocation(i * 20, 0);
        b.setSize(20, 100);

        panel.add(b, 0, -1);
    }

    for (int i = 0; i < 4; i++) {
        JButton b = new JButton();
        b.setBackground(Color.BLACK);
        b.setLocation(10 + i * 40, 0);
        b.setSize(20, 70);

        panel.add(b, 1, -1);
    }

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 300);
    frame.setVisible(true);
}

However, you need to lay out the piano keys in the correct order (:)) :

alt text

夏の忆 2024-10-12 05:16:33

我会编写一个自定义 PianoLayoutManager 并将黑键的 z 顺序设置得比白键更高。创建您自己的“约束”类,该类允许您添加如下组件:

add(new WhiteKey(), new PianoLayoutConstraint(WHITE, 1);
add(new WhiteKey(), new PianoLayoutConstraint(WHITE, 2);
...
add(new WhiteKey(), new PianoLayoutConstraint(WHITE, n);

add(new BlackKey(), new PianoLayoutConstraint(BLACK, 1);
add(new BlackKey(), new PianoLayoutConstraint(BLACK, 2);
...
add(new BlackKey(), new PianoLayoutConstraint(BLACK, m);

来自 使用 Swing 组件教程

注意: z 顺序决定组件绘制的顺序。 z 顺序最高的组件首先绘制,z 顺序最低的组件最后绘制。在组件重叠的情况下,具有较低 z 顺序的组件将绘制在具有较高 z 顺序的组件上。

这是一个丑陋的黑客,它使用空布局来帮助您入门。

import java.awt.Color;
import javax.swing.*;

class PianoComponent extends JPanel {

    PianoComponent() {

        setLayout(null);

        for (int i = 0; i < 20; i++) {
            JButton key = new JButton();
            key.setBackground(Color.WHITE);
            key.setLocation(i * 20, 0);
            key.setSize(20, 120);
            add(key);
            setComponentZOrder(key, i);
        }

        for (int i = 0; i < 20; i++) {
            int j = i % 7;
            if (j == 2 || j == 6)
                continue;

            JButton key = new JButton();
            key.setBackground(Color.BLACK);
            key.setLocation(i * 20 + 12, 0);
            key.setSize(16, 80);
            add(key);
            setComponentZOrder(key, 0);
        }
    }
}

public class Test {
    public static void main(String[] args) {
        JFrame jf = new JFrame("Piano!");
        jf.setSize(400, 200);
        jf.add(new PianoComponent());
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }
}

在此处输入图像描述

I would write a custom PianoLayoutManager and position the black keys with a higher z-order than the white buttons. Create your own "constraint" class that allows you to add components like this:

add(new WhiteKey(), new PianoLayoutConstraint(WHITE, 1);
add(new WhiteKey(), new PianoLayoutConstraint(WHITE, 2);
...
add(new WhiteKey(), new PianoLayoutConstraint(WHITE, n);

add(new BlackKey(), new PianoLayoutConstraint(BLACK, 1);
add(new BlackKey(), new PianoLayoutConstraint(BLACK, 2);
...
add(new BlackKey(), new PianoLayoutConstraint(BLACK, m);

From Using Swing Components tutorial trail

Note: The z-order determines the order that components are painted. The component with the highest z-order paints first and the component with the lowest z-order paints last. Where components overlap, the component with the lower z-order paints over the component with the higher z-order.

Here is an ugly hack that uses null-layout to get you started.

import java.awt.Color;
import javax.swing.*;

class PianoComponent extends JPanel {

    PianoComponent() {

        setLayout(null);

        for (int i = 0; i < 20; i++) {
            JButton key = new JButton();
            key.setBackground(Color.WHITE);
            key.setLocation(i * 20, 0);
            key.setSize(20, 120);
            add(key);
            setComponentZOrder(key, i);
        }

        for (int i = 0; i < 20; i++) {
            int j = i % 7;
            if (j == 2 || j == 6)
                continue;

            JButton key = new JButton();
            key.setBackground(Color.BLACK);
            key.setLocation(i * 20 + 12, 0);
            key.setSize(16, 80);
            add(key);
            setComponentZOrder(key, 0);
        }
    }
}

public class Test {
    public static void main(String[] args) {
        JFrame jf = new JFrame("Piano!");
        jf.setSize(400, 200);
        jf.add(new PianoComponent());
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }
}

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文