Multiple views in a JViewport? - java

Currently I have a nifty JViewport with a Jlabel set up and used as a view. I'm wondering if it's possible to use layered Jlabels as the Viewport's view. IE: I want to add new JLabels into a pre-existing Viewport.
Thanks!
EDIT: On StanislavL's advice, I'm now using a JLayeredPane within an JScrollPane. Currently there are two JLabels in the JLayeredPane, when I scroll the JScrollPane, the larger background image scrolls properly, by the smaller shipSprite remains in the same position. Any ideas how I can get them to scroll together?
public void initViewport() {
explorePort = new JScrollPane();
explorePort.setBounds(0, 0, retailWidth, retailHeight);
explorePort.setBackground(new Color(0, 100, 0));
explorePort.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
explorePort.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
ImageIcon background = Main.global.imgScaler.scaleImage(new ImageIcon("images/blankgrid.jpg"), retailWidth*2, retailHeight*2);
JLabel backSplash = new JLabel(background);
backSplash.setBounds(0, 0, retailWidth*2, retailHeight*2);
ImageIcon shipIcon = Main.global.imgScaler.scaleImage(new ImageIcon("images/ship.png"), Main.global.nodeWidth, Main.global.nodeHeight);
JLabel shipSprite = new JLabel(shipIcon);
shipSprite.setBounds(100, 100, Main.global.nodeWidth, Main.global.nodeHeight);
Main.global.gamePanel.add(backSplash, 0);
explorePort.setViewportView(backSplash);
Main.global.gamePanel.add(shipSprite, 1);
Main.global.gamePanel.add(explorePort, 2);
//explorePort.addMouseListener(this);
Main.global.gameFrame.addKeyListener(new ListenKey());
}

Use Layered pane to add multiple lables to container and place the container in JScrollPane
http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html

Related

How to make a JTable resize as the windows does?

I'm making an application in eclipse with swing and jfreechart and I have the following problem:
As you can see in the screenshot I have a frame with a few components. The problem is about the JTable, which always has the same size, no matter if I resize the window. I want the table to resize the same way other components do, like the ChartPanel at the right, and I don't know how to do it. The contentPane has a BorderLayout with three panels:
The scrollPane for the JTable (WEST)
The ChartPanel (CENTER)
The panel for the buttons (SOUTH)
The code for the JTable creation is this:
private JTable getTasksTable() {
if (tasksTable == null) {
tasksTable = new JTable(new DefaultTableModel(new Object[] { "ID", "Duration", "Due-Date" }, 0) {
private static final long serialVersionUID = 1L;
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
});
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
for (int i = 0; i < tasksTable.getColumnModel().getColumnCount(); i++) {
tasksTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer);
}
tasksTable.getTableHeader().setDefaultRenderer(centerRenderer);
tasksTable.getTableHeader().setBorder(new LineBorder(new Color(0, 0, 0)));
tasksTable.setBorder(new LineBorder(new Color(0, 0, 0)));
tasksTable.setFillsViewportHeight(true);
}
return tasksTable;
}
The scrollPane for the JTable (WEST), The ChartPanel (CENTER), The panel for the buttons (SOUTH)
Well, the way a BorderLayout works is that:
the components in the WEST/EAST are sized at the preferred width of the component.
The component in the CENTER gets the remaining width.
So in your case the scrollpane is a fixed width and the width of the chart panel varies.
If you want both the scrollpane and the chart panel width to change as the frame size changes you need to use a different layout manager.
In this case you could use a panel with a GridBagLayout for the scrollpane and chart components. Then GridBagLayout will assign space at the preferred size of each component. Then you can specify the weightx constraint for each component to specify what percentage of extra space goes to each component as the frame with is increased.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information on the constraints and working examples to get you started.

Border layout doesn't work as intended

I would like to achieve the below layout.
There are 6 panels. The 4 buttons at the top are one panel, and the 3 buttons at the right side of the image are also in one panel. Apart from those two there are 4 other panels as indicated by the borders. I tried the below code but displays everything in a scattered way.
mainPanel.add(topToolBarPanel,BorderLayout.PAGE_START);
mainPanel.add(lefsideToolBarPanel,BorderLayout.LINE_START);
mainPanel.add(descriptionPanel,BorderLayout.LEFT);
mainPanel.add(mapPanel,BorderLayout.CENTER);
mainPanel.add(propertiesPanel,BorderLayout.EAST);
mainPanel.add(tablePanel,BorderLayout.PAGE_END);
How can I achieve the design as shown in the image? I need all the panels to be arranged inside that mainPanel. I cannot use null layout though. Please advice.
After trashgod's answer :
JPanel gridPanel = new JPanel(new GridLayout(1, 0));
gridPanel.add(jInternalFrame1);
gridPanel.add(descriptionPanel);
mainPanel.add(gridPanel, BorderLayout.LINE_START);
mainPanel.add(topToolBarPanel,BorderLayout.PAGE_START);
mainPanel.add(tablePanel,BorderLayout.PAGE_END);
mainPanel.add(mapPanel,BorderLayout.CENTER);
mainPanel.add(PropertiesPanel,BorderLayout.LINE_END);
What I get :
Add lefsideToolBarPanel and descriptionPanel to a panel having GridLayout; add the new panel to the BorderLayout.
Panel p new Panel(new GridLayout(1, 0));
p.add(lefsideToolBarPanel);
p.add(descriptionPanel);
//mainPanel.add(lefsideToolBarPanel, BorderLayout.LINE_START);
//mainPanel.add(descriptionPanel, BorderLayout.LEFT);
mainPanel.add(p, BorderLayout.LINE_START);
There is no BorderLayout.LEFT. See also A Visual Guide to Layout Managers.
Addendum: Your updated question shows elements of topToolBarPanel, which should be added to PAGE_START, rather than LINE_START.
//mainPanel.add(topToolBarPanel,BorderLayout.LINE_START);
mainPanel.add(topToolBarPanel,BorderLayout. PAGE_START);
The width of the propertiesPanel and height of the tablePanel need to be increased. I used setSize()…
For the propertiesPanel, you can override getPreferredSize(), as discussed here. For the tablePanel, override getPreferredScrollableViewportSize() to customize the size of the table's enclosing JScrollPane, for example.
I suggest using a JLabel as your "layout" to use exact positioning of yout objects with setBounds(x, y, width, height). It would look similar to this :
JButton button = new JButton("Text or Image");
JLabel backgr = new JLabel();
JFrame frame = new JFrame("JLabel as Layout");
button.setBounds(100, 200, 340, 40);
backgr.add(button);
frame.add(backgr);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocation(40, 40);
frame.validate();
frame.setVisible(true);
I know that this is just a quick example for you, but I think it should do for explanation... so just add everything on the backgr JLabeland your good to go. Quick and dirty example but the a way to go.

JScrollPane acts funny inside of a JOptionsPane

I have tried to add a scroll view to a JOptionsPane, so that the information window can handle more text. It does add a scroll pane to the window. However, it acts funny on scrolling. The first visible text is shown clearly, but when you start scrolling, the text parts will overlap each other, until the text area is all black.
Do you have an explanation of how this can be and maybe a solution to the problem?
My code looks like this:
public void showInfoNoTranslation(String info) {
frame.requestFocusInWindow();
// create a JTextArea
JTextArea textArea = new JTextArea(info, 6, 25);
textArea.setEditable(false);
textArea.setBackground(new Color(255, 255, 255, 0));
textArea.setBorder(BorderFactory.createEmptyBorder());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
// if (textArea.getLineCount() > 5) {
JScrollPane scrollPane = new JScrollPane(textArea);
JOptionPane.showMessageDialog(_frame, scrollPane, "title", JOptionPane.INFORMATION_MESSAGE);
}
Call textArea.setOpaque(false); instead of setting it's background-color to fully transparent and it will work.
From the docs:
public void setOpaque(boolean isOpaque)
If true the component paints every pixel within its bounds. Otherwise, the component may not paint some or all of its pixels, allowing the underlying pixels to show through.
The default value of this property is false for JComponent. However, the default value for this property on most standard JComponent subclasses (such as JButton and JTree) is look-and-feel dependent.

JScrollPane is not adding to my JList.

Im trying to add a Scroll bar to my JList. I want only 4 headings to be available on my JList at a time. When I add a JList and run my program, the JList disappears from the screen. Can someone help me fix this problem? I am using Java Eclipse.
This is my code:
songList1 = new JList (ListData);
songList1.setVisibleRowCount(4);
songList1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
songList1.setBounds(300,100,100,200);
panel.add(new JScrollPane(songList1);
You can try one of the following:
set panel's layout or
set scroll panes bounding area by scrollPane.setBounds()
Just an oversight:
songList1 = new JList(ListData);
songList1.setVisibleRowCount(4);
songList1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane songList1ScrollPane = new JScrollPane(songList1)
//songList1ScrollPane.setBounds(300, 100, 100, 200);
songList1ScrollPane.setBounds(10, 10, 100, 200);
panel.setLayout(null); // Absolute positioning
panel.add(songList1ScrollPane);
...
add(panel); // Or so
Of course the panel should have an appropiate layout.

Getting appropriate dimensions of a Swing component

I was trying out JLayeredPane. So, in the following code, I created a JLayeredPane and a JLabel. I added the label to the layered pane, which I added to a JPanel. This panel was then added to a JFrame.
public static void main(String[] args) {
frame = new JFrame("LayeredPane Example");
frame.setPreferredSize(new Dimension(500,500));
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new Dimension(400, 400));
JLabel label = new JLabel("Label on LayeredPane");
label.setLocation(200, 200);
System.out.println("Width " + label.getWidth() );
label.setBounds(20, 20, 400, 40);
layeredPane.add(label);
layeredPane.setLayer(label, 10, 1);
frame.setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.add(layeredPane);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
Now the problem is that if I do not have the statement label.setBounds(20, 20, 400, 40);, then the label does not appear on the layered pane. This raises two questions:
Why is setBounds so important?
Probably a part of my previous questions answer, the label had an initial height and width of 0 before setting bounds, which might be the reason setBounds is important. In that case, I want to know how can I determine appropriate bounds for a Swing component when I am adding it to a JLayeredPane. (If my bounds are less than the appropriate size of the component, the component will appear hidden)
Edit:
The first question was answered earlier in more detail here.
Regarding:
Why is setBounds so important: A JLayeredPane uses essentially a null layout, and whenever you use null layouts, you the coder are completely responsible for both the size and position of the components that you add. That's simply the rules of this layout.
How to determine the appropriate bounds: One thing I've done is simply to let the component tell me what its preferredSize is and then use it for its size:
myJLabel.setSize(myJLabel.getPreferredSize());
Another thing I've done is to use non-opaque JPanels for each layer of my JLayeredPane, give these JPanels appropriate layouts and then add my components to the appropriate layer JPanel. I then use a listener to be sure that the layer JPanel's size matches that of its JLayeredPane container.

Categories