2

Well sounds little weird, but I am trying to overlap twoJButtons (here jButton1 and jButton2).I am using NetBeans GUI builder for this.Nothing extraordinary,I am using JLayeredPane to make it possible.

 jLayeredPane1.add(jButton1, javax.swing.JLayeredPane.DEFAULT_LAYER);

Well it does overlap,but the JButton shows its self up,when Clicked by a mouse. A screenshot will make it clear:

enter image description here

(take highlighted portion as a mouse pointer)

and

When the mouse pointer is clicked on the next JButton,it comes up,hiding the first JButton. enter image description here

but,I don't want the second JButton to pop up(overlap 1stJButton) when clicked by a mouse. How can i do this??Well, I think this may go critical.

Here is the code,if required:

public class NewJFrame1 extends javax.swing.JFrame {

public NewJFrame1() {
    initComponents();
}

private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jLayeredPane1 = new javax.swing.JLayeredPane();
    jButton1 = new javax.swing.JButton();
    jButton2 = new javax.swing.JButton();
    jLayeredPane2 = new javax.swing.JLayeredPane();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.setBackground(new java.awt.Color(51, 51, 51));

    jButton1.setText("jButton1");
    jButton1.setBounds(0, 40, 73, 23);
    jLayeredPane1.add(jButton1, javax.swing.JLayeredPane.DEFAULT_LAYER);

    jButton2.setText("jButton2");
    jButton2.setBounds(40, 40, 73, 23);
    jLayeredPane1.add(jButton2, javax.swing.JLayeredPane.DEFAULT_LAYER);

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGap(98, 98, 98)
                    .addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGap(139, 139, 139)
                    .addComponent(jLayeredPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addContainerGap(161, Short.MAX_VALUE))
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(58, 58, 58)
            .addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(jLayeredPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(31, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    pack();
}
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame1().setVisible(true);
        }
    });
}


private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLayeredPane jLayeredPane1;
private javax.swing.JLayeredPane jLayeredPane2;
private javax.swing.JPanel jPanel1;


}

UPDATE :

If I am not clear, here i go again.

1) I don't want to make separate buttons,they should be overlapped .

2)Overlapping area may differ,the size of the button.

3)The second JButton should not come above the 1st JButton,when clicked.(Solution for this,but not for how to layout the buttons.)

4)There may be confusion,which button was clicked,but its ok for me.

joey rohan
  • 3,505
  • 5
  • 33
  • 70

3 Answers3

3

What does layout manager have to do with it?

@Patricia Shanahan has pointed out the problem with overlapping the buttons. One solution is to let the layout do the work. In the example below, butonPanel has a centered FlowLayout by default. It adopts the preferred size of the buttons in any Look & Feel.

Addendum: Ah, you want the buttons to overlap but retain a stable z-order. Because rendering is controlled by the button's UI delegate, a subclass of ButtonUI, the effect is Look & Feel dependent. For example, both com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel and com.apple.laf.AquaLookAndFeelbehave as you want, while many others do not. Absent creating your own delegate, shown here, you might try to adapt the approach shown here, which hides the button's and uses an overlaid image. Depending on the enclosing container's layout, either FlowLayout or GridLayout(1, 0) should work.

As an aside, don't let the GUI designer dictate your GUI design!

image

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/a/14075990/230513 */
public class LayoutTest {

    private void display() {
        JFrame f = new JFrame("LayoutTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JPanel(){

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 150); // content placeholder
            }
        }, BorderLayout.CENTER);
        JPanel buttonPanel = new JPanel(); // default: FlowLayout, centered
        buttonPanel.add(new JButton("Button1"));
        buttonPanel.add(new JButton("Button2"));
        f.add(buttonPanel, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new LayoutTest().display();
            }
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Also consider `OverlayLayout`, seen [here](http://stackoverflow.com/a/13437388/230513) among [other](http://stackoverflow.com/q/13436787/230513) related approaches. – trashgod Dec 28 '12 at 21:31
  • @joeyrohan: I've elaborated above. – trashgod Dec 29 '12 at 12:17
  • `rendering is controlled by the button's UI delegate, a subclass of ButtonUI, the effect is Look & Feel dependent` +1.Well,that means there is no shortcut,I have to customize it myself?Am I right? – joey rohan Dec 29 '12 at 14:14
1

Overlapping the buttons creates confusion about which button was clicked. I suggest resizing the button that you want to be underneath so that the "hidden" part is no longer part of the button. That way, clicks in the common area will go only to the top button.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • Also consider an alternate [layout manager](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html). – trashgod Dec 28 '12 at 16:41
  • `clicks in the common area will go only to the top button` I want both the buttons to function as it is,if i resize the button,it will,still,come on the top.What I dont want to. – joey rohan Dec 28 '12 at 18:49
  • @joeyrohan: Fair question; I've elaborated [here](http://stackoverflow.com/a/14075990/230513). – trashgod Dec 28 '12 at 21:32
  • @trashgod are you not misunderstanding my question like last time? – joey rohan Dec 29 '12 at 06:50
  • @joeyrohan: Very likely, but I maintain that Patricia's observation is a useful caveat. – trashgod Dec 29 '12 at 12:21
  • @trashgod in what way? Question is OutOfBond for that answer – joey rohan Dec 29 '12 at 14:07
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/21864/discussion-between-trashgod-and-joey-rohan) – trashgod Dec 29 '12 at 14:18
  • Not overlapping the buttons as far as the API is concerned puts you in total control. If you want a click in a certain area to go to both buttons, and know it will go to one of them, you can have your buttons support listening for clicks in a portion of their own area. The reduced size button underneath would listen to the top button for clicks in its logical area. – Patricia Shanahan Dec 29 '12 at 14:48
0

Your issue is that you are adding the buttons to the same layer (the default one). You should number the layers. Hence for your code it would be something like this:

jLayeredPane1.add(jButton1, Integer.valueOf(0));
   
jLayeredPane1.add(jButton2, Integer.valueOf(1));

Notice that you have to use the wrapper (Integer not int)

ATP
  • 2,939
  • 4
  • 13
  • 34