I've reccently run into issues with indexing my tabs and though I'd give it some concrete ordering by using the setComponentAt method. Here's my code:
public ContainerPane() {
this.setLayout(new BorderLayout());
myPlayerManagerPane = new PlayerManagerPane();
myGameManagerPane = new GameManagerPane();
myCharacterManagerPane = new CharacterManagerPane();
myPaneTab = new JTabbedPane(JTabbedPane.TOP);
myPaneTab.addTab("Character",myCharacterManagerPane);
myPaneTab.addTab("Player",myPlayerManagerPane);
myPaneTab.addTab("Games",myGameManagerPane);
System.out.println(myPaneTab.getTabCount());
//myPaneTab.setEnabledAt(1, false);
//myPaneTab.setEnabledAt(2, false);
myPaneTab.setComponentAt(0, myPlayerManagerPane);
myPaneTab.setMnemonicAt(0, KeyEvent.VK_1);
myPaneTab.setComponentAt(1, myCharacterManagerPane);
myPaneTab.setMnemonicAt(1, KeyEvent.VK_2);
myPaneTab.setComponentAt(2, myGameManagerPane);<---outOfBoundsException
myPaneTab.setMnemonicAt(2, KeyEvent.VK_3);
add(myPaneTab);
}
So for the count I have, 3 tabs (according to me, and getTabCount()), and I am counting from 0 (correct?). I'm setting the last index the last component that I have. But I still have this printing to screen:
3 <---from tabCount
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 2 >= 2
Where am I tripping up, is there an easier way to order my panes?
Edit: Commenting out the setComponent methods, and putting in a for loop I get this output:
There are 3 tabs!
Tab at 0 is Character
Tab at 1 is Player
Tab at 2 is Games
And uncommmenting one pair of methods at a time, I get only 2, of the one I've not overwritten, and one of the ones I've now set.
Is setComponentAt removing duplicates? Should I ever have fewer than 3 tabs with my set up? Does JTabbedPanel have odd behaviour for duplicate panes?
You get an error due to changes you are trying to do - by putting some of the panes into another position you automatically remove another tab. That is why you get the error - there is less than 3 tabs after some of the changes (you can check that outputting tabs amount after each of "setComponentAt" operations).
Simple remove all tabs you want to reorder and readd them using either addTab or insertTab - that will get the job done without any errors.
Looking at source code of the setComponentAt you can see that component you're setting is removed:
int count = getComponentCount();
Component children[] = getComponents();
for (int i = 0; i < count; i++) {
if (children[i] == page.component) {
super.remove(i);
}
}
next this component is set as page's component (overriding last present component on that page):
page.component = component;
So setting order of existing tab component you end up with 2 tabs.
I'm not sure how or why setComponentAt wasn't working, though it could be the fact that tabs use a Vector and I've heard they are bad.
If you want to have a fixed order of adding, just use insertTab Like so:
myPaneTab.insertTab("Games",null, myGameManagerPane,"CharacterManagerPane",2);
Where null is for the icon, and doesn't accept it as an empty argument.
This way you know in your source code the index of the tab. The only issue with this is that you can't add a new tab at an index past the current tabCount (which you can find via getTabCount), i.e. you can't count 1,3,4 with your tabs!
I'm sure you could write a new JTabb Class, and overload the insertTab method to do something more helpful but it might obsfuscate where the tab is (I.e this way you could tell it put the tab at index 2 and it goes into index 1.
If you want your tabs in another order, add them in another order:
myPaneTab = new JTabbedPane(JTabbedPane.TOP);
myPaneTab.addTab("Player",myPlayerManagerPane);
myPaneTab.addTab("Character",myCharacterManagerPane);
myPaneTab.addTab("Games",myGameManagerPane);
Et voilĂ .
Related
i need to test a sorting function of a table. My problem is, that the developer implemented something like "lazy-loading" for the rows - the rows (div-elements of an ag-grid-table) only appears in the DOM, when they are in the view. So if you scroll through the table, the top elements disappear (even cant find the divs through dev-tools in chrome). Thats why i cant read all elements under the table and work with them - i need to scroll with my WebDriver through the table and read every row and write them into an array, where i can test, if the result is sorted.
WebElement table = Helper.driver.findElement(By.xpath("hidden"));
Actions builder = new Actions(Helper.driver);
//here i read the total number of elements in the table from a string, which displayed the total number directly under the table
String totalNumberOfRows = Helper.driver.findElement(By.xpath("hidden")).getText();
int totalInt = Integer.parseInt(Arrays.asList(total.split(" ")).get(1));
String[] sortedTableColumn = new String[totalInt];
List<WebElement> tableRows = table.findElements(By.className("ag-row")); //all active Elements, which exist in the DOM at the point, where the user looks. Mostly around 15 elements (35 total in my example)
for(int i = 0; i<totalInt; i++) {
builder.moveToElement(tableRows.get(i)).perform(); //scroll through the elements
sortedTableColumn[i] = Arrays.asList(tableRows.get(i).getText().split(" ")).get(0); //dont ask, its necessary to get the first part of the string
}
System.out.println(Arrays.toString(sortedTableColumn));
assertTrue(Ordering.natural().isOrdered(Arrays.asList(sortedTableColumn)));
problem is, that the loop end with an error, because the tableRow has only 15 elements and the loop want to go further. Pretty understandable.
But I dont know how to handle this. I need something like "take the tableRows, go one step down (tableRows will change), put this new tableRows and the old ones in a new array and kill duplicates. AND be sure, that this is the new List, where i use the iterator "i".
Has anyone an idea to fix/complete my code or maybe a better way to test sorting funtions of dynamic loaded tables?
I am creating a new label which I want to position precisely 130px next to an existing one. I am not familiar with layouts and would rather absolutely position my labels. My code is as follows:
playerLabels[index] = new javax.swing.JLabel();
playerLabels[index].setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/image001".png")));
playerLabels[index].setBounds(playerLabels[index - 1].getX() + 130, playerLabels[index - 1].getY(), playerLabels[index - 1].getWidth(), playerLabels[index - 1].getHeight());
panel.add(playerLabels[index]);
playerLabels[index].setVisible(true);
I am not getting any errors, but even though my labels are created. They do not appear at the desired position.
Does anybody know what I can do?
I agree that it's usually better to use a LayoutManager. That said, here's an article Oracle posted that describes how to do this:
Doing Without a Layout Manager (Absolute Positioning)
The code that you have posted will not depict the issue. Please give a sample code that can replicate your problem.
To address your problem, if you set the position of element manually (setBounds), you need to first set the container layout null and secondly you need to set the size of panel where you are adding those jlabel.
1.
this.setLayout(null);
2.
panel.setSize(900,900); // whatever the size you need.
So I got an assignment in Java to make an 8 piece puzzle, and I chose to use JButtons for tiles (don't know if that's even possible). I've got the buttons to appear in a random order when starting it, but I have no idea how to make the tiles able to move when you click on them. So I'm wondering if someone could just point me in the right direction? I've come to conclusion that I need to use Actionlistners and saw an old user here getting tip of doing Actionlistners on every button, but I am having trouble with knowing what to writ, and do I put this in another class?
Any help is very much appreciated!
The product so far:
To make it easier, you could add ninth button which is transparent and not clickable. Every but should has his id, which would also tell hes position.
11 12 13
21 22 22
31 32 33
So for every button you already assign his random number. Now just like you use actionlistners to detect which button is clicked. And when is clicked you check if button that is neighbor is transparent. If transparent you would swap there values, one would become visible,other transparent and not clickable.
To get button neighbors you would use + and - operations.
int leftNeighbour = id - 1;
int rightNeighbour = id + 1;
int topNeighbour = id - 10;
int bottomtNeighbour = id + 10;
I assume that all buttons are saved in an array so you just go like this:
for(Button tempButton : Buttons)
{
if(leftNeighbour > 0 && leftNeighbour == tempButton.id) //we check first if button id is OK, then we compere it with tempButtons id
{
int tempButtonValue = tempButton.value;
tempButton.value = currentButton.value;
currentButton.value = tempButtonValue ;
makeButtonTransparent(tempButton);
break; //we found over neighbor so we can stop for loop
}
//then you check conditions for other neighbor id's. Butt first condition is allays different
}
I hope that I didn't make it over complicated, but this is idea that I got in few minutes, when I was thinking how I would make it with buttons. There is probably some better way to set ID's to buttons, and check if they are neighbors.
I have a list of items to display in Swing. For simplicity, imagine that each item consists of only a name. I want the user to be able to order these items by dragging and dropping them above/below each other. What's the best way to achieve this?
Alternatively, could this perhaps be accomplished in using a JList, with an "up" and "down" button that would move the selected item up/down in the list. This would require updating the graphical display instantly on each click (I don't know how to do this), and saving the new order by getting the items in the list in their current order (which I also don't know how to do).
Or might a drag-and-drop solution be more feasible?
It'd probably be easier to implement this with the JList solution you mention, so I'll give you some pointers on that (I'm not very experienced with D&D).
Basically, you want to have three components: a JList and two (one up, one down) JButtons. You'll also probably want a custom list model. If you're unfamiliar with models or list models, check out this tutorial. Otherwise, read on.
In the list model class (e.g., ReorderableListModel), go ahead and define two methods: public void moveUp(int index) and public void moveDown(int index).
The code for moveUp is as follows:
if (index > 0) { // error checking
// Swap the given index with the previous index.
// (where `list` is the name of your list variable)
Collections.swap(list, index, index - 1);
}
// Finally, notify the `JList` that the list structure has changed.
fireContentsChanged(this, index - 1, index);
moveDown is similar:
if (index < getSize() - 1) {
Collections.swap(list, index, index + 1);
}
fireContentsChanged(this, index, index + 1);
Now, we need to implement the action listeners for the buttons. For the up button, go try this listener code:
// First, move the item up in the list.
listModel.moveUp(list.getSelectedIndex());
// Now, set the selection index to keep the same item selected.
//
// If you use the default list selection interval, setting the index to -1
// will do nothing (so it's okay, we don't need error checking here).
list.setSelectedIndex(list.getSelectedIndex() - 1);
Add a similar "move down" method and you're done!
With respect to "updating the graphical display instantly on each click," that's what the fireContentsChanged method in the model class does. JList will do the updating for you.
It is a functionality hard to achieve using just swing. Have you heard about JavaFX? It is a great graphic framework to work with if you want to achieve more dynamic functionality in desktop applications, take a look to this article: http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html
Here you will be able to find links with more information, as well as some examples. Best regards.
I need my vertex label displayed entirely inside vertex bounds. I mean if my label is too long then part of it will be displayed outside the vertex box. Is there any way to automatically split label into multiple lines and make it fit the vertex bounds? This line breaks should be recalculated after vertex resize. Can i do it using styles? mxUtils.wordWrap() seems to be the way but i cannot figure out how to use it properly. Give me an example of using it please. Thanks for your answers
Another similar question: Calculate the display width of a string in Java
Abstract:
Graphics.getFontMetrics + FontMetrics.stringWidth
From this, I suppose you could create a List<String> and add the words of the text one at a time until you reach your max length, then add a new node to the list for the overflow. Finally, append each node in the List to each other with a line break in between.
On another note, from what research I did, it seems jGraphX runs on swing. Swing now supports HTML. Here's a link to further info: http://docs.oracle.com/javase/tutorial/uiswing/components/html.html.
I will see if I can get a quick test coded up, but that must wait until I get home.