Displaying notification count in CodaNameone - java

I am facing issues in displaying notification count against an icon. It should be displayed at right top corner.
First created button with padding and margin as zero and set the image to button.
FlowLayout buttonLayout = new FlowLayout();
buttonLayout.setAlign(Component.CENTER);
buttonLayout.setValign(Component.TOP);
Container buttonContainer = new Container(buttonLayout);
buttonContainer.setUIID("IconContainer");
Button button = new Button(buttonImage);
button.setUIID("ButtonLabelNew");
buttonContainer.addComponent(button);
The created a notification count container and laid it over button
FlowLayout countLayout = new FlowLayout();
countLayout.setAlign(Component.RIGHT);
countLayout.setValign(Component.TOP);
Container countContainer = new Container(countLayout);
Label countLabel = new Label(displayCount);
countLabel.setUIID("backgroundLabel");
countContainer.addComponent(countLabel);
/*Adding Button and Notification Count to ItemContainer*/
Container itemContainer = new Container(new LayeredLayout());
itemContainer.addComponent(buttonContainer);
itemContainer.addComponent(countContainer);
Now added the text below the button
BoxLayout iconLayout = new BoxLayout(BoxLayout.Y_AXIS);
Container iconContainer = new Container(iconLayout);
Label iconText= new Label(buttonText);
iconText.setUIID("Label");
iconContainer.addComponent(0,itemContainer);
iconContainer.addComponent(1,iconText);
FInally created a grid and added icon containers to the grid
GridLayout gridLayout = new GridLayout(numRows, MAX_ITEMS_PER_ROW);
Container gridContainer = new Container(gridLayout);
gridContainer.setUIID("LogoContainer");
for (int indx = 0; indx < itemContainers.length; indx++)
{
gridContainer.addComponent(itemContainers[indx]);
}
approvalsWorklist.addComponent(BorderLayout.CENTER,gridContainer);

The image is positioned at the right hand side but the component is larger than the icon so you see the image positioned where the components are sized.
There are two ways to solve this for you.
Set a padding or margin on countContainer so the count will be spaced and placed in the right location. This has the drawback of having to tune based on a uniform icon size which might not be the case but its a relatively simple approach.
I'm assuming the components are placed in a GridLayout which means they all have the exact same size. You will wrap each element in the grid layout in a FlowLayout or a an absolute center BorderLayout they will take up their preferred size internally and then the badge will be positioned exactly within the icon edge.

Related

Adding JButtons in for loop

JAVA Swing Problem
I want to create a list of JButtons based on a list of strings, which represents the button text.
In my first step, I collect my data for the button texts from an external text file. This data is stored in the data variable.
List<String> data = ReadFile("texts.txt")
Now I want to create the list of JButtons, named buttons. There I set their text and their Bounds. The Bounds are relative to the index, so the buttons are placed below each other. Finally, I add the button to the frame and to the buttons list.
List<JButton> buttons = new ArrayList<>();
for (int index = 0; index < data.size(); index++) {
JButton button = new JButton();
button.setText(data.get(index));
button.setBounds(0, index*50, 100, 50);
add(button);
buttons.add(button);
But when I execute this, the last Button ends big, the first ones also disappear when I don't hover over them, but that's based on the fact, that the last button ist placed above:
Picture of the executed script
The last button has the size of the frame, doesn't matter, if I resize the frame:
Picture of the resized screen
I hope someone can help me or tell me where I can find help. Thanks.
the last Button ends big, the first ones also disappear when I don't hover over them,
That is because by default the content pane of the JFrame uses a BorderLayout. When you add a component to the BorderLayout the button is added to the CENTER. However, only a single component can be added to the CENTER, so only the size/location of the last component added is managed by the BorderLayout.
Don't attempt to set the size/location of your components manually. It is the job of a layout manager to do this. In your case you can use a couple of panels with different layout so align your button in a column on the left. Something like:
JPanel buttonPanel = new JPanel( new GridLayout(0, 1) );
for (int index = 0; index < data.size(); index++) {
JButton button = new JButton();
button.setText(data.get(index));
button.setBounds(0, index*50, 100, 50);
//add(button);
buttonPanel.add( button );
buttons.add(button);
}
add(buttonPanel, BorderLayout.LINE_START);
Try the above code and you will notice that the buttons are all the same size, but the size keeps changing as the height of the frame changes.
So to prevent this resizing we need to allow the button to be displayed at their preferred height by using an additional layout manager:
//add(buttonPanel, BorderLayout.LINE_START);
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(buttonPanel, BorderLayout.PAGE_START);
add(wrapper, BorderLayout.LINE_START);
Read the Swing tutorial on Layout Manager for more information and examples.

How to resize a panel if a child component is added with it at runtime?

I have a window, containing a frame and JScrollBar. JScrollBar has panel, whose size i want to change at run time if any child component is added with it. Child component size is constant and should not change.
I have Horizontal scrollBar disabled. So if placement of Child Component exceeds panel width, it should go to next row and panel height should change automatically.
Here is code snippet
JScrollPane scrollPane = new JScrollPane();
menuPane = new JPanel();
menuPane.setLayout(new FlowLayout(FlowLayout.CENTER));
scrollPane.setViewportView(menuPane);
MenuTray mtFile = new MenuTray("File"); // MenuTray extends JPanel
menuPane.add(mtFile);
Menu mNew = new Menu((new ImageIcon(MenuScreen.class.getResource("/com/srinar/res/New.png"))), "New"); // Menu extends JLabel
mtFile.add(mNew);
frame.getContentPane().add(scrollPane);
. So if placement of Child Component exceeds panel width, it should go to next row and panel height should change automatically
The FlowLayout will wrap components automatically but it doesn't recalculate the preferred size with the components on the new row.
Instead you can use the Wrap Layout which extends FlowLayout so it can recalculate the preferred size correctly when components wrap.
Note, the wrapping will occur even if you don't use a scroll pane.

Reduce gap between JPanels

I have a simple Class StatPanel that extends JPanel and has a few JTextFields, a JCheckBox, and a couple JLabels. The panel is going to be used as a series of panels used to display information and allow the user to edit the data in some of the JTextFields and I will probably have about 40 of them all stacked together on the side of the program in a JScrollPane JPanel. The layout I am using is a GridLayout(0,1).
I have them working but when the are in the scroll panel they are spaced too far apart vertically. I have tried changing the margins, changing the spacing in the GridLayout and changing the margins of the various items. Nothing I do seems to make them closer.
This is the constructor for the StatPanel class:
public StatPanel(String statName, String statAbility){
super();
this.skillName = statName;
this.setAlignmentY(CENTER_ALIGNMENT);
isClassSkill = new JCheckBox();
statLabel = new JLabel(skillName);
statTotalField = new JTextField(maxLength + 1);
statTotalField.setHorizontalAlignment(JTextField.CENTER);
statAbilityLabel = new JLabel("= " + statAbility + " ");
statAbilityModField = new JTextField(maxLength);
statAbilityModField.setHorizontalAlignment(JTextField.CENTER);
statSeperator1 = new JLabel(" + ");
statRanksField = new JTextField(maxLength);
statRanksField.setHorizontalAlignment(JTextField.CENTER);
statSeperator2 = new JLabel(" + ");
statMiscModField = new JTextField(maxLength);
statMiscModField.setHorizontalAlignment(JTextField.CENTER);
this.add(isClassSkill);
this.add(statLabel);
this.add(statTotalField);
this.add(statAbilityLabel);
this.add(statAbilityModField);
this.add(statSeperator1);
this.add(statRanksField);
this.add(statSeperator2);
this.add(statMiscModField);
}
}
When I use it in the program it looks like this:
As I am going to stack so many of them I want them pretty much one on top of the other but I can seem to remove the gap between them.
How is this done?
Thank you for your help.
Check out the FlowLayout API. By default a JPanel uses a FlowLayout with default horizontal/vertical gap of 5 pixels. You will want to change the vertical gap used by the layout manager. So at the top of your method you will want to add:
setLayout( new FlowLayout(...) );
Edit:
Once you change the gap you will also lose the gap at the top/bottom of the main panel so you might want to add an EmptyBorder to the panel.

Buttons in a horizontal panel don't want to align right

I have a horizontal panel with 3 buttons: Back, Next and Cancel. I've made horizontal alignment to the right, but only Next and Cancel buttons follow this alignment.
Here is the code:
HorizontalPanel buttons = new HorizontalPanel();
buttons.setWidth("100%");
cancel = new Button("Cancel");
next = new Button("Next");
back = new Button("Back");
buttons.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
buttons.add(back);
buttons.setCellWidth(back, "98%");
buttons.add(nextBtn);
buttons.setCellWidth(next, "1%");
buttons.add(cancel);
buttons.setCellWidth(cancel, "1%");
The problem is with this panel width. But if I delete it, all my buttons are left aligned. As a workaround I can use false button, that will be invisible and has cell width = 97%, the cell width of back button is 1%. But this is not what I need, because inspite of small amount of memory this invisible button consumes, it is still a memory :)
What is going wrong with this alignment? Maybe something is wrong with panel width? Hope for your help, thank you in advance.
There is setCellHorizontalAlignment() property in HorizontalPanel. With it you can give alignment to its widgets.
Try following:
buttons.setCellHorizontalAlignment(backButton, HasHorizontalAlignment.ALIGN_RIGHT);
buttons.setCellHorizontalAlignment(nextButton, HasHorizontalAlignment.ALIGN_RIGHT);
buttons.setCellHorizontalAlignment(cancelButton, HasHorizontalAlignment.ALIGN_RIGHT);
You can achieve this much easier using css:
FlowPanel panel = new FlowPanel();
panel.setWidth("100%");
cancel = new Button("Cancel");
cancel.getElement().getStyle().setFloat(Float.RIGHT);
next = new Button("Next");
next.getElement().getStyle().setFloat(Float.RIGHT);
back = new Button("Back");
back.getElement().getStyle().setFloat(Float.RIGHT);
panel.add(back);
panel.add(nextBtn);
panel.add(cancel);

How to get the coordinate of Gridlayout

I set my JPanel to GridLayout (6,6), with dimension (600,600)
Each cell of the grid will display one pictures with different widths and heights.
The picture first add to a JLabel, and the JLabel then added to the cells.
How can retrieved the coordinate of the pictures in the cells and not the coordinate of cells? So far the out give these coordinate which equal height and width even on screen the pictures showed in different sizes.
e.g.
java.awt.Rectangle[x=100,y=100,width=100,height=100]
java.awt.Rectangle[x=200,y=100,width=100,height=100]
java.awt.Rectangle[x=300,y=100,width=100,height=100]
The reason why I used GridLayout instead of gridBagLayout is that, I want each pictures to have boundary. If I use GridBagLayout, the grid will expand according to the picture size.
I want grid size to be in fix size.
JPanel pDraw = new JPanel(new GridLayout(6,6));
pDraw.setPreferredSize(new Dimension(600,600));
for (int i =0; i<(6*6); i++)
{
//get random number for height and width of the image
int x = rand.nextInt(40)+(50);
int y = rand.nextInt(40)+(50);
ImageIcon icon = createImageIcon("bird.jpg");
//rescale the image according to the size selected
Image img = icon.getImage().getScaledInstance(x,y,img.SCALE_SMOOTH);
icon.setImage(img );
JLabel label = new JLabel(icon);
pDraw.add(label);
}
for(Component component:components)
{
//retrieve the coordinate
System.out.println(component.getBounds());
}
EDITED: I have tried this but not working :-(
for(Component component: pDraw.getComponents()){
System.out.println(((JLabel)component).getIcon());
}
How can I get output like these?
java.awt.Rectangle[x=300,y=100,width=50,height=40]
java.awt.Rectangle[x=400,y=400,width=60,height=50]
Do your images appear at the desired size ?
i think so.
Anyway, from what your code seems to do, I guess it gets the labels size, and not the icons size. JLabel, like any JComponent, are in fact Container instance. As such, their size depends upon constraints. As a consequence, in a GridLayout, a JLabel will have the size of a cell, whereas the contained Icon will have the size of the image.
As a consquence, to get image size, you have to call ((JLabel) component).getIcon() to be able to retrieve effective image dimension.

Categories