When I run this program it appears as an empty window until you fullscreen, then it can be resized as you like, why is it doing this/how do I stop it?
the program is very basic just a menubar and two panels split.
public class SplitPane {
public static void main(String[] args) {
window view = new window();
}
private static class window extends JFrame {
public window() {
this.setSize(1000, 750);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//menubar is here, must lower code quantity for stack
//panels
//graph half
JPanel graphRep = new JPanel();
//Background colour - graphRep.setBackground(Color.RED);
graphRep.setVisible(true);
String graphTitle = "Textual Representation.";
Border graphBorder = BorderFactory.createTitledBorder(graphTitle);
graphRep.setBorder(graphBorder);
//text half
JPanel textRep = new JPanel();
textRep.setVisible(true);
String textTitle = "Graphical Representation.";
Border textBorder = BorderFactory.createTitledBorder(textTitle);
textRep.setBorder(textBorder);
//splitpane
JSplitPane splitPane = new JSplitPane();
splitPane.setSize(600, 750);
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerSize(10);
splitPane.setDividerLocation(250);
splitPane.setLeftComponent(graphRep);
splitPane.setRightComponent(textRep);
this.add(splitPane);
}
}
this.setVisible(true);
You are making the frame visible BEFORE you add components to the frame. The layout manager is never invoked so the size of all the components remains (0, 0) so there is nothing to paint.
The frame should be made visible AFTER all the components have been added to the frame.
And the code should be:
frame.pack();
frame.setVisible();
So each component is displayed at its proper size. Don't hardcode the size() because you don't know what the size of a users screen might be.
Related
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.
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.
I'm having trouble trying to add a horizontal scroll bar to a JFrame that has a canvas. I draw an images onto the canvas and sometimes these images over-run the screen so I want a scroll bar to enable the user to see them.
Here is the key section in the code, if any other code is needed please let me know and i'll edit.
Could anyone point out what i'm doing wrong ?
Many Thanks J
public class TheFrame extends JFrame {
private static ThePanel canvas;
private String deckImagesToUse;
/**
* The constructor creates a Frame ready to display the cards
*/
public TheFrame(String cardImgFile) {
// Calls the constructor in the JFrame superclass passing up the name to
// display in the title
super("Window title");
//Using users choice of cards
deckImagesToUse = cardImgFile;
// When you click on the close window button the window will be closed
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// This has North, East, South, West and center positions for components
setLayout(new BorderLayout());
// This is what we will draw on (see the inner class below)
canvas = new ThePanel();
setSize(700, 300);
this.add(canvas, BorderLayout.CENTER);
//Scroll Bar
JScrollPane scrollPane = new JScrollPane(canvas);
//scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
this.getContentPane().add(scrollPane);
int desiredWidth = (Pack.cardsInPlay.size() * 70);
Dimension d = new Dimension(desiredWidth,300);
canvas.setPreferredSize(d);
setVisible(true); // Display the window
}
canvas = new ThePanel();
setSize(700, 300);
this.add(canvas, BorderLayout.CENTER);
The setting size and adding to this is futile because later scrollpane ignores it.
When your image is bigger than the JScrollPane just call canvas.setPreferredSize(imageWidth, imageHeight);
I have a JFrame, in this JFrame I have a JPanel that I draw on, this Panel can be any size and so I placed it into a JScrollpane to let me scroll when the panel is larger than the window screen size.
Unfortunately does not work as I expected:
Making the JFrame window smaller than the JPanel size does not show scroll bars
The JScrollPane size now seems locked to the size of the JPanel I have added to it, where as before it resized to the bounds of it's JFrame window (it still kinda does this but only vertically now?!)
The JPanel seems to assume the size of the JScrollpane regardless of what I set for preferred size
I am sure I'm doing something stupid, if someone could point out what I would be most grateful!
JPanel imageCanvas = new JPanel(); // 'Canvas' to draw on
JScrollPane scrollPane = new JScrollPane();
// set size of 'canvas'
imageCanvas.setMinimumSize(new Dimension(100,100));
// Scroll pane smaller then the size of the canvas so we should get scroll bars right?
scrollPane.setMinimumSize(new Dimension(50,50));
// Add a border to 'canvas'
imageCanvas.setBorder(BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
scrollPane.setViewportView(imageCanvas);
setPreferredSize() is the trick, setMinimumSize() and even setSize() on the component will be ignored by JScrollPane. Here's a working example using a red border.
import java.awt.*;
import javax.swing.*;
public class Scroller extends JFrame {
public Scroller() throws HeadlessException {
final JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.red));
panel.setPreferredSize(new Dimension(800, 600));
final JScrollPane scroll = new JScrollPane(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(scroll, BorderLayout.CENTER);
setSize(300, 300);
setVisible(true);
}
public static void main(final String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Scroller().setVisible(true);
}
});
}
}
// suggest a size of 'canvas'
_ImageCanvas.setPreferredSize(new Dimension(100,100));
// Scroll pane smaller then the size of the canvas so we should get scroll bars right?
_ScrollPane.setPreferredSize(new Dimension(50,50));
// ..later
_Frame.pack();
Set preferred size on the canvas.
Increase dimensions 100,100 is too small atleast on my computer.
You may want to use new GridLayout(1,1); for you JFrame if you want the scrollpane to expand when you expand the frame.
As far as I remember there are 2 options:
define the preferredSize of _ImageCanvas
create a subclass of JPanel and implement Scrollable: http://docs.oracle.com/javase/7/docs/api/javax/swing/Scrollable.html
For more details, see the Javadoc:
http://docs.oracle.com/javase/7/docs/api/javax/swing/JScrollPane.html
Check out the Scrollable interface, this may help with the sizing issues.
These two method maybe helpful:
boolean getScrollableTracksViewportWidth();
boolean getScrollableTracksViewportHeight();
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.