Java Swing - Scroll Pane With Custom Graphics - java

I currently have the code below.
public class cRunningView extends JInternalFrame {
static final int xOffset = 30, yOffset = 30;
public cRunningView() {
// Get name;
super("RUNNING", true, // resizable
false, // closable
true, // maximizable
true);// iconifiable
System.out.println("##" + "p.getName()");
// ...Then set the window size or call pack...
setSize(500, 200);
// Set the window's location.
setLocation(xOffset * 0, yOffset * 0);
JScrollPane scrollPane = new JScrollPane();
}
}
My aim is to have a JInternalFrame with a number of buttons and a box/rectangle on half of the screen.
Within this box i want to be able to draw graphics for e.g. Draw oval from x,y to x,y.
I've tried looking at examples but see to get my self more confused than i did to begin. All my code is working e.g. Showing the main GUI window and my internal frame opening but i cant seem to find a good tutuirol/starting point to do graphics within a JScrollPane.
Please note i dont have to use a JScrollPane i just thought i would be a good idea cause it would give the graphics a border round it.
Before anyone moans about the question i think it is valid AND I DONT want the code to be given to me on a plate, i'd rather know and understand what im doing so i can advance my knowledge and be able to help others !
Do i have to make another class and do
JScrollPane myPane = JScrollPane(graphicsClass)
then do everything with paint() then or is there someway to create a graphic and do it without another class?
If i do :
JScrollPane scrollPane = new JScrollPane();
Graphics temp = scrollPane.getGraphics();
temp.setColor(new Color(1, 22, 33));
temp.fillOval(60, 0, 120, 60);
scrollPane.paint(temp);
It throws errors.
Thanks

You don't do Graphics in a scrollpane. Also, don't use the getGraphics() method to do custom painting.
Custom painting is done by overriding the paintComponent() method of a JPanel or JComponent. Then if required you can add the panel to a scrollpane and add the scrollpane to your frame. Don't forget to set the preferred size of the panel so scrolling will work.
Start by reading the Swing tutorial on Custom Painting.

Related

How to make my JFrame components dynamically scale when resizing the window, without hard-coding position and size values?

I'm learning java through university and I've been taught the basics of making a java program and designing GUIs. Maximizing a window after running my program makes all the JFrame components stay in place while grey fills the rest of the space. Here's an example of how it looks like:
JFrame window normally, Maximized window before "fix".
After failing to find a solution I came up with a band-aid solution which is to get the component locations and just move them with hard-coded values when the jframe is maximized. This was not an elegant solution and every jframe in my java course project increased in the number of elements on screen. Is there any piece of code to make my components move and resize automatically and dynamically?
Here's what I've tried so far:
First I obtained the positions of components through 2D points:
Point managementLoginBtnLocation, empLogLocation, logoLocation, customerBtnLocation, welcomeLblLocation, contactBtnLocation, aboutBtnLocation, mainMenuBtnLocation;
//Constructor and rest of code...
public final void getOriginalComponentLocations()
{
managementLoginBtnLocation = managementLoginBtn.getLocation();
empLogLocation = empLoginBtn.getLocation();
logoLocation = shopLogo.getLocation();
customerBtnLocation = customerBtn.getLocation();
welcomeLblLocation = welcomeLbl.getLocation();
contactBtnLocation = contactBtn.getLocation();
aboutBtnLocation = aboutBtn.getLocation();
mainMenuBtnLocation = mainMenuBtn.getLocation();
}
//This method is called within the constructor.
I implemented the ComponentListener Interface and added a component listener to my jframe. Then I made it so when the jframe's size changes, it changes the size of the jlabel used for background art. And if the label's width is greater than 800 (the default I used while designing) it moves the components and doubles their size and font size. When the jframe is minimized the label will go back to the default size so I made a method to revert the font sizes, because I found the component sizes and locations reset automatically.
public void componentResized(ComponentEvent e)
{
//Resizing the background label and setting its icon to a resized version of its current icon.
backgroundMainArt.setSize(this.getWidth() - 16, this.getHeight() - 21);
ImageIcon icon = new ImageIcon("C:\\Program Files\\OMOClothingStore\\Resources\\Main menu\\main menu background art.jpg");
Image img = icon.getImage();
Image newImage = img.getScaledInstance(backgroundMainArt.getWidth(), backgroundMainArt.getHeight(), Image.SCALE_FAST);
icon = new ImageIcon(newImage);
backgroundMainArt.setIcon(icon);
if(backgroundMainArt.getWidth() > 800) //When the size of the label is greater than default
{
//I move the components, enlarge the buttons and zoom the font size
moveComponents();
enlargeBtns();
zoomBtnsFontSize();
}
else //When the label is back to its original size
{
//I revert the font sizes as button sizes and positions reset automatically
revertBtnsFontSize();
setLogoIconAndBackgroundArtAndWelcomeLbl();
}
}
public void moveComponents()
{
moveLogo();
moveManagementLoginBtn();
moveEmployeeLoginBtn();
moveCustomerBtn();
moveWelcomeLbl();
moveContactInfoBtn();
moveAboutBtn();
moveMainMenuBtn();
}
public void moveLogo()
{
ImageIcon logoIcon = new ImageIcon("C:\\Program Files\\OMOClothingStore\\Resources\\Shared resources\\OMO Clothing Store logo.png");
Image logoImg = logoIcon.getImage();
Image newLogoImage = logoImg.getScaledInstance(250, 250, Image.SCALE_DEFAULT);
logoIcon = new ImageIcon(newLogoImage);
shopLogo.setIcon(logoIcon);
Point newLogoLocation = new Point();
newLogoLocation.x = (logoLocation.x * 2) + 200;
newLogoLocation.y = (logoLocation.y * 2) + 30;
shopLogo.setLocation(newLogoLocation);
}
//The rest of the "moveX" methods follow the same pattern as moveLogo()
public void enlargeBtns()
{
managementLoginBtn.setSize(410, 94);
empLoginBtn.setSize(410, 94);
customerBtn.setSize(410, 94);
}
public void zoomBtnsFontSize()
{
customerBtn.setFont(sizeBtn.getFont());
//sizeBtn is a JButton that has a font size of 24. I found that just creating a new Font object with bigger size here made the font way larger for some reason.
empLoginBtn.setFont(sizeBtn.getFont());
managementLoginBtn.setFont(sizeBtn.getFont());
}
public void revertBtnsFontSize()
{
empLoginBtn.setFont(new Font("Segoe UI", Font.PLAIN, 14));
managementLoginBtn.setFont(new Font("Segoe UI", Font.PLAIN, 14));
customerBtn.setFont(new Font("Segoe UI", Font.PLAIN, 14));
}
I split the moving of the components into many methods inside other methods because I found it easier to keep up with.
This worked. Here's how it looks like when running the JFrame: Maximized window after "fix". But moving on to other JFrames, they are more intricate and have many more components - extra buttons, panels with other components in them, menu bars, etc.
Is there a better approach to fixing this? Or do I just remove the ability to resize and move on?

JTable only shows the right border of the table

I have a JTable and I want to make a tic tac toe themed table. I have managed to get rid of three borders without really knowing how...
Here's my code:
public class Table extends JPanel {
public static void main( String[] args ) {
JFrame jFrame = new JFrame();
JTable table = new JTable(3, 3);
table.setBounds(90, 20, 200, 200);
for(int i = 0; i < 3; i++) {
table.setRowHeight(i, 67);
}
table.setBackground(Color.black);
table.setGridColor(Color.white);
table.setForeground(Color.white);
// content pane so I can set the background
jFrame.getContentPane().add(table);
jFrame.getContentPane().setBackground(Color.black);
jFrame.setSize(400, 400);
jFrame.setLayout(null);
jFrame.setVisible(true);
}
}
I also have some stuff that initializes the table more like setting values but I don't think that will matter but I can add it if you want. So how could I get the right border of the table to disappear too?
When I compile this code, the top, left and bottom borders are not visible
You can usesetBorder method with a LineBorder in order to fill it:
table.setGridColor(Color.white);
table.setBorder(BorderFactory.createLineBorder(table.getGridColor()));
By the way, setLayout(null) and setBounds is a bad practice that is going to give you hard time in the future (plus it is not user-friendly, since you cannot resize your frame and won't work in different screen sizes). Try to use LayoutManagers and let them do the work for you.
Also, take a look at initial threads. All swing applications should run on their own thread and not in the main thread.

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 won't scroll - Java Desktop Application

So I'm developing an application. I have a huge problem, and I know I'm probably overlooking something stupid, but my scollpanes aren't scrolling. Could someone please checkout the following code and tell me what I did wrong?
rotationPanel = new JPanel();
rotationPanel.setLayout(null);
rotationLabels = new JLabel[countStarters(team)];
resetXY(5,5);
for(int i = 0; i < countStarters(team); i++){
rotationLabels[i] = new JLabel(team.rotation.get(i).getName());
rotationLabels[i].setForeground(Color.BLACK);
addComp(rotationLabels[i], rotationPanel, labelX, labelY, labelSize);
labelY += 25;
}
//Other Code in between
rotationBar = new JScrollPane(rotationPanel);
rotationBar.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
rotationBar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
rotationBar.setPreferredSize(new Dimension(520, 150));
addComp(rotationBar, this, 15, 75, new Dimension(520, 150));
//addComp method:
public void addComp(JComponent comp, JComponent panel, int xPos, int yPos, Dimension size){
comp.setLocation(xPos,yPos);
comp.setSize(size);
panel.add(comp);
}
The resetXY() method just sets the x and y position for the components
Any help would be appreciated
Cheers,
Dave
JScrollPane uses either the components preferredSize or if implemented Scrollable#getPreferredScrollableViewportSize to determine what size the scroll pane and its view port can be. When the viewport is larger the the scroll pane, the scroll bars will appear
The Swing API has being designed around the use of the layout manager, choosing to do without the will cause you no end of problems and additional work.
Layout managers help you over come the difference between systems, including font rendering, DPI, screen sizes and rendering pipelines to mention a few.
I think your JPanel needs to have its size set, otherwise it will shrink to fit the JScrollPane.

java jscrollpane

I have a problem with displaying the components of a JScrollPane. Let me first explain the context. I've got one big splitpane:
center = new JSplitPane(JSplitPane.VERTICAL_SPLIT, p, p1);
center.setDividerLocation(0.9);
center.setDividerSize(3);
center.setResizeWeight(1);
center.setContinuousLayout(true);
The p pane is shown the right way, no problem here. But the p1 pane won't be displayed, i can see the empty bottom-part of the splitPane, but that's all.
JPanel p = new JPanel();
p.add(canvas);
JPanel p1 = new JPanel();
p1.add(canvasPropPane);
The canvasPropPane is a scrollPane that i initialize like this:
VolumeSizeAndPosition volum = new VolumeSizeAndPosition();
canvasPropPane = new JScrollPane(volum);
volume was tested on an independent frame and have been shown the right way.
I tried showing on the canvasPropPane a simple button canvasPropPane.add(wildButton); and it has a strange behavior: it paints the button only after i hover the mouse over it's location; at repaint (after resizing the scrollpane) it disappears.
I've solved similar problems by calling invalidate() on all of the underlying nested Swing objects. So for your particular question p.invalidate() and p1.invalidate() may help. I believe this strange behavior to be a bug in Swing.

Categories