Swing: Showing a transparent Panel hovering over another Panel - java

I want to show a textArea showing some text (will show log lines) , and have an animated gif hoovering above it. I tried the solution described here , but all I get is a grey screen. Hints?
public class TestLayeredPanes {
private JFrame frame = new JFrame();
private JLayeredPane lpane = new JLayeredPane();
public TestLayeredPanes() {
frame.setPreferredSize(new Dimension(600, 400));
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
//Build the animated icon
JLabel buildingIcon = new JLabel();
buildingIcon.setIcon(new ImageIcon(this.getClass().getResource(
"/com/ct/tasks/cmviewer/gui/progress_bar.gif")));
JPanel iconPanel = new JPanel();
iconPanel.add(buildingIcon);
//Build the textArea
JTextArea textLog = new JTextArea("Say something");
JPanel textPanel = new JPanel();
textPanel.add(new JScrollPane(textLog));
//Add the panels to the layered pane
lpane.add(textPanel, 0);
lpane.add(iconPanel, 1);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new TestLayeredPanes();
}
}

Try putting your animated GIF on the glass pane of your root pane:
http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html

JXLayer make easier to do that. Look at JXLayer samples.
You also can take a look at code of XSwingX

Since you started with a working example, why did you remove lines of code from the example you copied?
Layered panes don't use a layout manager therefore the size of your components are (0, 0), so there is nothing to display. The setBounds(...) method in the example are there for a reason.

Related

Adding JScrollPane to JPanel with another panels inside

i been working on some bigger project lately but couldn't figure it out why JScrollPane wouldn't work. I have never used it before and I read many solved problems about it on stackOverflow and other programming forums but non of the code were looking similar to mine to help me implement my method.
this is new project i made to make it short and show some examples.
Red colour is main panel that will contain another panel/JScrollPane inside that will be colour black
and i would like to make this Jpanel with colour black to be scrollable and hold any number of that white JPanels that might be from 0 to a 100+
public class ScrollablePane {
private JFrame frame;
private JPanel panelCopy;
private JPanel panel;
private JPanel container;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ScrollablePane window = new ScrollablePane();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ScrollablePane() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
panel = new JPanel();
panel.setBackground(Color.RED);
panel.setBounds(0, 0, 434, 261);
frame.getContentPane().add(panel);
panel.setLayout(null);
container = new JPanel();
container.setBackground(Color.BLACK);
container.setBounds(10, 10, 414, 241);
container.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
panel.add(container);
for(int i = 0; i < 20; i++) {
if(i > 0) {
panelCopy = new JPanel();
panelCopy.setPreferredSize(new Dimension(400, 40));
container.add(panelCopy);
}
}
}
}
if you want to use a JScrollPane, then your code actually needs to use a JScrollPane. The code you posted doesn't even create a JScrollPane.
If you want the panels to display vertically then don't use a FlowLayout. The FlowLayout is a horizontal layout. You could use a BoxLayout or a GridBagLayout.
Why do you create the "panel" variable and add it the the content pane? The content pane of the frame already is a JPanel that uses a BorderLayout. There is no need to add another panel
Don't use a null layout!!! Swing was designed to be used with layout managers. Scrolling won't work if the panel added to the scroll pane uses a null layout.
So in your case the basic logic might be something like:
Box container = Box.createVerticalBox();
// add you child panels to the container.
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(container, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(wrapper);
frame.add(scrollPane, BorderLayout.CENTER);
Note the "wrapper" panel is used to prevent the panels from expanding in size when the scroll pane is larger then the preferred size of the "container" panel.
Try:
//JScrollPane scrollPane = new JScrollPane(wrapper);
JScrollPane scrollPane = new JScrollPane(container);
to see the different result.

Set margin about a JPanel of GridLayout in Swing

I'm trying to setup the margin about the JPanel that it has inside the GridLayout refer to the JFrame, but I don't found the solution using other answer. I don't know if it's important problem, but also it show only the first button before I go to each button with mouse.
The image is an example, I want to setup the JPanel to start from the corner of the grid of image, because the image has a border (not from code, but from decoration board), the blue squares are the button inside the GridView, but I'm trying to fit the gridView to the image draw grid, using the set property (using proportion of pixel).
public class Gui extends JPanel implements View {
private final JPanel gui = new JPanel(new BorderLayout(3, 3));
private JButton[][] chessBoardSquares = new JButton[5][5];
private JPanel chessBoard;
private ImageIcon ArrayWithoutPlayer[] = new ImageIcon[7]; //{1,2,3,4,10,11,12}
private ImageIcon ArrayWithPlayer[] = new ImageIcon[3]; //{1,2,3}
private JFrame frame; //This is the whole frame
public Gui() {
createAndShowGUI();
}
private void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TextDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window.
frame.setSize(800, 800);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
//frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
//frame.pack();
frame.getContentPane().add(new ImagePanel( setImageIconFromUrl("/home/amministratore/Documenti/Java/ing-sw-2020-palini-rigutti-vangi/image/SantoriniBoardR.png",800,800).getImage()));
chessBoard = new JPanel(new GridLayout(0, 5));
chessBoard.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
//chessBoard.setLayout(new BoxLayout());
//chessBoard.setPreferredSize(new Dimension(400, 100));
chessBoard.setBackground(Color.blue);
//chessBoard.setAlignmentX((float) (2.2/21)*frame.getWidth());
//chessBoard.setAlignmentY((float) (2.2/21)*frame.getHeight());
//chessBoard.setMaximumSize(new Dimension((16/21)*frame.getWidth(),(16/21)*frame.getHeight()));
//chessBoard.setAlignmentX(JLabel.LEFT_ALIGNMENT);
//chessBoard.setBorder(new LineBorder(Color.BLACK));
Insets buttonMargin = new Insets(0,0,0,0);
for (int ii = 0; ii < chessBoardSquares.length; ii++) {
for (int jj = 0; jj < chessBoardSquares[ii].length; jj++) {
JButton b = new JButton();
b.setMargin(buttonMargin);
b.setBorder(null);
b.setBorderPainted(false);
b.setContentAreaFilled(false);
b.setOpaque(false);
chessBoardSquares[ii][jj] = b;
b.setText("AA");
chessBoard.add(chessBoardSquares[ii][jj]);
}
}
//chessBoard.setOpaque( false );
chessBoard.setBackground(new Color(255,0,0,0));
frame.dispose();
frame.add(chessBoard);
frame.setVisible(true);
//chessBoardSquares[0][0].setIcon( ArrayWithoutPlayer[0]); //This is the method to set Icon inside the button
}
}
I'm trying to setup the margin about the jpanel that it has inside the GridLayout
//b.setMargin(buttonMargin);
//b.setBorder(null);
//b.setBorderPainted(false);
I don't think you need all that code.
Instead just set the Border of the button:
b.setBorder( new EmptyBorder(5, 5, 5, 5) );
Edit:
frame.getContentPane().add(new ImagePanel(...));
…
frame.add(chessBoard);
First of all frame.getContentPane().add(…) and frame.add(…) is the same thing. That is the component will be added to the content pane. The second format is just a shortcut for the first.
So you are attempting to add two components to the BorderLayout.CENTER. This will not work as the BorderLayout will only support a single component in any location.
Swing was designed with a parent/child relationship so it appears you want something like:
JFrame (content pane)
ImagePanel
chessBoard
So your logic should be something like:
ImagePanel background = new ImagePanel(…);
background.setLayout( new BorderLayout() );
background.add(chessPanel, BorderLayout.CENTER);
frame.add(background, BorderLayout.CENTER);
Now you have your parent/child relationship between the components.
frame.setSize(800, 800);
Don't set the size of the frame. (800, 800) is the wrong size. If your ImagePanel is (800, 800) then the frame must be bigger because the frame also includes the title bar and the border.
So instead your logic should be:
frame.pack();
frame.setVisible(true);
The pack() method will allow the frame to determine its own preferred size AFTER all the components have been added to the frame.
Note:
In you ImagePanel class you will also need to implement the getPreferresSize() method of your Image. This will allow the pack() method to work properly. Read the section from the Swing tutorial on Custom Painting for a working example.

Adding JPanel created on netbeans on top of to anotherJpanel created programatically

I have a panel that I am drawing some stuff on and I want to have an interface on top of it. I created an interface as a JPanel on netbeans, visually. But interface is not displayed properly.
Here is my code
public static void main(String[] args) {
JFrame frame = new JFrame("WorldGen");
Interface inter = new Interface();
JLayeredPane lpane = new JLayeredPane();
frame.setPreferredSize(new Dimension(600, 400));
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
lpane.setBounds(0, 0, 600, 400);
lpane.add(panel, new Integer(0), 0);
lpane.add(inter, new Integer(1), 0);
panel.setBounds(0,0,600,400);
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main = new Main();
}
Panel is declared as a static JPanel.
static JPanel panel = new JPanel()
Here is my result:
This is the Interface class that is created in netbeans visually
When I add this line:
inter.setBounds(0,0,600,400);
inter.setOpaque(true);
this is what I get:
Just a blank screen. I don't expect it to be transparent since I set it to opaque myself but It seems I have another problem. The button is not showing whether I set it to opaque or not.
Why is the button not showing? I am hoping that the button will still be visible when I set opaque to false, after I resolve this problem.
I've solved it by creating a JFrame in netbeans visually, adding a JPanel to it. Then using that panel(by overriding the paint method) to draw my image.

Any other way to add scrollbar to JPanel other than JscrollPane

I have developed a desktop application. Now in that app I want to add panel with a scrollbar. I am trying using JScrollPane, but its not working.
JPanel paraJPanel = new JPanel();
JScrollPane SP_para_list = new JScrollPane(paraJPanel);
add(SP_para_list).setBounds(10,30,250,350);
This way I am adding scrollbars to panel. But it shows only empty panel with borders. It is not showing components in the panel. Although I have added several labels in it. Is it correct? Is there any other way to add scroll bar to panel.
Thanks in advance
You need to set the PreferredSize for the panel, to make the scrollbar show up, like below.
even you do not set a layout, the panel already has a default layout set.
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel panel = new JPanel()
{
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 1000);
}
};
panel.add(new JLabel("Test1"));
panel.add(new JLabel("Test2"));
frame.getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
frame.setSize(600, 800);
frame.setVisible(true);
}

How can I place a component in a JLayeredPane right below an existing component?

I have a JTextField, and right below it I want to show a JLabel placed in a JLayeredPane (I will use it for autosuggestions later on).
How can I place my JLabel in JLayeredPane right below the JTextField?
Here is some code I have, and the current result shown in the screenshot below:
public static void main(String[] args) {
JTextField field = new JTextField();
JLabel lbl = new JLabel("Hello");
lbl.setBackground(Color.YELLOW);
lbl.setOpaque(true);
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setLayout(new GridLayout(0,1));
layeredPane.add(lbl, (Integer) (JLayeredPane.POPUP_LAYER - 10));
layeredPane.setPreferredSize(field.getPreferredSize());
JPanel panel = new JPanel(new BorderLayout());
panel.add(field, BorderLayout.NORTH);
panel.add(layeredPane, BorderLayout.SOUTH);
JFrame frame = new JFrame();
frame.add(panel);
frame.setSize(200, 360);
frame.setVisible(true);
}
Second try:
public static void main(String[] args) {
JTextField field = new JTextField();
JLabel lbl = new JLabel("Hello");
lbl.setBackground(Color.YELLOW);
lbl.setOpaque(true);
lbl.setBounds(field.getBounds().x, field.getBounds().y,
field.getBounds().width, field.getBounds().height);
JPanel popPanel = new JPanel(new BorderLayout());
popPanel.add(lbl, BorderLayout.NORTH);
popPanel.setLocation(field.getLocation().x+10, field.getLocation().y+20);
popPanel.setPreferredSize(field.getPreferredSize());
JFrame frame = new JFrame();
JLayeredPane layeredPane = frame.getRootPane().getLayeredPane();
layeredPane.setLayout(new GridLayout(0,1));
layeredPane.add(popPanel, (Integer) (JLayeredPane.POPUP_LAYER - 10));
JPanel panel = new JPanel(new BorderLayout());
panel.add(field, BorderLayout.NORTH);
frame.add(panel);
frame.setSize(200, 360);
frame.setVisible(true);
}
Add the layeredPane to the "CENTER", not the SOUTH.
However, your understanding a layed pane seems to be a little confused. You use a layered pane when you want multiple components to be displayed on top (stacked?) of one another. You are still using the layered pane in 2 dimensions which is unnecessary. YOu can just use a panel for this.
If you want to popup a list of suggestions then you should just use a JPopupMenu and position it below the text field. Read the section from the Swing tutorial on Bringing up Popup Menus.
First of all, I don't think you should use a JLayeredPane for that, but just a permanent label.
If you do use a layered pane, you'll have to compute where the text field ends (y = field.getY() + field.getHeight()) and set your JPanel at 'panel.setLocation(0, y)' inside the JLayeredPane (provided the JLayeredPane has the same starting position as the underlying JFrame). You could equivalently position the JLayeredPane at (0, y) and put the label at (0, 0) within that layered pane.
You have to make sure this is done every time the components are resized.
why not using AutoComplete ComboBox / JTextField and if you don't want to display JComboBox, then there is AutoCompleted JTextField, and for somehow reduced autosuggestions, would be better look for undecorated JDialog/Window with JTable with one TableColum and without TableHeaded in the JScrollPane, just with plain RowSorter, very simle job

Categories