I'm making a simple currency converter GUI (nothing fancy) as I am going to try and incorporate live exchange rate updates for each time the user opens the application. When creating the layout, I have decided to simple convert 3 currencies (GBP, USD and EUR). I have the respective flags in 2 columns, each column has one of the 3 flags. One column is for the user to select the initial currency and the other is the desired currency to exchange to; as seen below
I have created a String array which contains the words "Pounds", "Dollars" and "Euros" and I am wanting to put these labels to the left of the flags (for clarity of the application for the user as not every user may know which currency belongs to which country.
I created a loop which would create a label and assign it to the left of the flags, it is supposed to make a "pound" label, then a "Dollar" then a "euro" each time traversing the Y axis south so that they aligns with the flags and it will then reset the array count to go back to the correct string, move along the x-axis and repeat it again. It is however not doing this at all, the only result I get is the text "Pounds " to the left of the first United Kingdom flag; as seen below:
below is my code if anyone can see as to why this is happening.
This is the code which adds the flags to the panel
addToMain(GBP1, mainPage, 100,100,100,100); //alligns a United Kingdom Flag to left Column
addToMain(GBP2, mainPage, 375,100,100,100); //alligns a United Kingdom Flag to right Column
addToMain(USD1, mainPage, 100,200,100,100); //alligns a United States Flag to left Column
addToMain(USD2, mainPage, 375,200,100,100); //alligns a United States Flag to right Column
addToMain(EUR1, mainPage, 100,300,100,100); //alligns a European Union Flag to left Column
addToMain(EUR2, mainPage, 375,300,100,100); //alligns a European Union Flag to right Column
This is the loop which should add the text labels to the left of the flags
currencyName = new String [] {"Pounds", "Dollars", "Euros"};
for(int i = 0; i <= 7; i++)
{
int count = 0; //declares a counter for the position in the currencyName array to grab the correct text for label
xLabelAlign = 50;
yLabelAlign = 100;
if(count == 3)
{
count = 0; //resets to create both columns of labels in the application moves to the next column.
xLabelAlign = 325;
yLabelAlign = 100;
}
JLabel temp = new JLabel(currencyName[count]); //creates a new label and names it the string at position count
temp.setFont(new Font("SERIF", Font.BOLD, 20));
temp.setForeground(Color.WHITE);
addToMain(temp, mainPage, xLabelAlign, yLabelAlign ,100,100); //adds it to the panel
yLabelAlign +=100; //moves position ready for the next text label.
count++; //grabs the next label in the currencyName string array.
}
This is the method which adds things to the panel. I have used the set bounds methods to add things to the panel so i can position them where i want easily
private void addToMain(JComponent c, JPanel p, int x, int y, int w, int h)
{
c.setBounds(x,y,w,h);
p.add(c);
}
Any help would be greatly appreciated.
Fast solution: Move your int count = 0; xLabelAlign = 50; yLabelAlign = 100; out of the for loop. Loop in the range of [0,5].
Good solution: Java layouts tutorial
Related
I have a large table created with Java SWT which I can sort columnwise in various ways. But whenever I sort a column, the table starts displaying the 1st row and I could not find a way to move the table to display a specific row, e.g. the last selected row.
Any idea is appreciated!
Gerald
You can use `Table.setTopIndex" to set the row shown at the top of the table window. So to centre a row you might use something like:
static void showCentredRow(Table table, int rowToShow)
{
Rectangle clientArea = table.getClientArea();
int itemHeight = table.getItemHeight();
int visibleRows = clientArea.height / itemHeight;
int topRow = Math.max(rowToShow - (visibleRows / 2), 0);
table.setTopIndex(topRow);
}
I've exhausted my understanding of Tableau. I'm trying to color every icon below the risk average the color red, and above the color green. Here is an attempt at an articulation in Java of my intention (this code may not be correct, but I want the intention translated into Tableau).
This is my Tableau code that doesn't work:
IF [Commercial Services] <= [Risk Average] *The variable I want to create*
THEN "Red"
ELSEIF [Commercial Services] > [Risk Average]
THEN "Green"
END
Here's the Java code I think is closer to what I need converted:
final int NUM_ROWS = 39;
int count = 0;
while(count < NUM_ROWS) {
if(count.commercial_services < count.risk_average) {
shape.color = "Red";
} elseif(count.commercial_services > count.risk_average) {
shape.color = "Green";
} else {
shape.color = "Blue";
}
count++;
}
Please help me create a variable that I could use to color each risk in reference to the risk average.
I have attached a spreadsheet and an image for reference.
Thanks in advance.
That is not the way Tableau works. For such purposes, you should first create a flag-like calculated field to form values according to your conditions. And then use that field as a shape or color identifier dragging it to the Marks card.
So for your case you may create a field like below (which is almost the same you did), which means it will have the value of "Red" for CS<=RA condition and "Green" for the other condition. Only that Tableau does not know what to do with these string variables at the moment. You may assign -1 or 1 instead of these strings, it does make no change.
IF [Commercial Services] <= [Risk Average]
THEN "Red"
ELSE "Green"
END
And now you have new column in your data which have "Red" or "Green" values at each row. You may now drag this field to Marks card and select is as Color or as normal pill and select its type as Shape then use standard arrows or make your custom shapes according to your needs. At this phase, you will be selecting with which colours or shapes should your "Red" & "Green" values be represented by.
I or someone else might be in more help if you share your tableau workbook with what you have done so far.
With the Java GridBagLayout why is there a large space to the right of the first JTextField (Labeled A) before the column but the last two JTextField's B and C behave as expected without unwanted spaces between them and how can I eliminate the space?
I've attached an image below to show the problem along with the code.
/* Label digital timer */
gbcRightPanel.gridx = 0;
gbcRightPanel.gridy = 0;
rightPanel.add(labelDitigalTimer, gbcRightPanel);
/* Text Field Hours */
gbcRightPanel.gridx = 0;
gbcRightPanel.gridy = 1;
gbcRightPanel.weighty = 1;
rightPanel.add(jtxtFieldHours, gbcRightPanel);
/* Label colon */
gbcRightPanel.gridx = 1;
gbcRightPanel.gridy = 1;
rightPanel.add(new JLabel(":"), gbcRightPanel);
/* Text Field Minuites */
gbcRightPanel.gridx = 2;
gbcRightPanel.gridy = 1;
rightPanel.add(jtxtFieldMinuites, gbcRightPanel);
/*Colon*/
gbcRightPanel.gridx = 3;
gbcRightPanel.gridy = 1;
rightPanel.add(new JLabel(":"), gbcRightPanel);
/* Text Field Seconds */
gbcRightPanel.gridx = 4;
gbcRightPanel.gridy = 1;
rightPanel.add(jtxtFieldSeconds, gbcRightPanel);
A GridBagLayout works with cells consisting of row/columns.
The first row has a single column. The second row has 5 columns.
So the width of column 1 is the width of the largest component in all the rows of the first column which happens to be your label so you see the extra space.
One way to change this is to have the label take up 5 columns. So before you add the label you need to use:
gbcRightPane.gridWidth = 5;
rightPanel.add(labelDitigalTimer, gbcRightPanel);
gbcRightPane.gridWidth = 1; // reset for the other components.
Now the label will appear above all 5 of the components. You can then determine whether you want the label centered or left justified by specifying an appropriate constraint.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information about the constraints and working examples.
Another approach is to use nested panels. So you can create a separate panel for the text fields and colon labels. Then in the GridBagPanel you add the label and the panel as two separate components.
Read up on the other layout managers from the tutorial to get an idea how each layout manager works to you can effectively nest panels to get the desired layout.
gbcRightPanel.weighty = 1;
Makes the panel have a multiplicator / weigth of 1.0, so any space on x-axis which is left over after all other elements have been placed, go to the first column.
Try to add an fourth column and give this column a bigger weight.
I have a table in libgdx which is supposed to have 6 buttons, organised into 2 rows. Here's my code:
elementsTable.clear();
String[] colors = new String [6];
colors[0] = "red";
colors[1] = "orange";
colors[2] = "yellow";
colors[3] = "purple";
colors[4] = "blue";
colors[5] = "green";
String category = currentCategory.name();
category = category.substring(0, category.length()-1).toLowerCase(); //removes the last character because otherwise there would be an extra 's'
int count = 0;
for(String color : colors) {
ButtonStyle buttonStyle = new ButtonStyle();
buttonStyle.up = cellsSkin.getDrawable(category + "_" + color);
Button button = new Button(buttonStyle);
button.addListener(toolBoxListener);
button.setName(category + "_" + color);
button.setSize(toolBoxButtonSize, toolBoxButtonSize);
elementsTable.add(button).pad(toolBoxButtonPadding);
count ++;
if (count == Math.ceil((colors.length/2d))) elementsTable.row();
}
That's the filling. My buttons are of 6 different colors so I loop over the array with the color names to access the skin to get the drawable for the buttons. This part seems to work because when I debug and look at the table, it has the 6 buttons in there with the right size.
Then I set the position and size of my table and add it to the stage.:
elementsTable.setSize(toolBoxWidth, 500/(float)(3*toolBoxButtonSize+6*toolBoxButtonPadding)*elementsTable.getHeight());
elementsTable.setPosition(195, 30);
stage.addActor(elementsTable);
The stage has an orthographic camera set that should scale things down just fine.
However, what I get is this:
Another strange thin is that when I look at the table's height and width in debug mode, it says 0 even thoug there are elements in it that all have the corrct size.
Can anyone help me?
If you have any further questions on the problem, please ask! I tried to give a detailed description, but I am happy to answer your questions.
It seemsits just the position. 30 is too low for the Y:
elementsTable.setPosition(195, 30);
Try 150 for example:
elementsTable.setPosition(195, 150);
Remember the coordinate system that Libgdx (and OpenGL) use is with Y going up.
I got a relatively easy question - but I cannot find anything anywhere to answer it.
I use a simple SWT table widget in my application that displays only text in the cells. I got an incremental search feature and want to highlight text snippets in all cells if they match.
So when typing "a", all "a"s should be highlighted.
To get this, I add an SWT.EraseItem listener to interfere with the background drawing. If the current cell's text contains the search string, I find the positions and calculate relative x-coordinates within the text using event.gc.stringExtent - easy.
With that I just draw rectangles "behind" the occurrences.
Now, there's a flaw in this. The table does not draw the text without a margin, so my x coordinate does not really match - it is slightly off by a few pixels! But how many?? Where do I retrieve the cell's text margins that table's own drawing will use? No clue. Cannot find anything.
Bonus question: the table's draw method also shortens text and adds "..." if it does not fit into the cell. Hmm. My occurrence finder takes the TableItem's text and thus also tries to mark occurrences that are actually not visible because they are consumed by the "...".
How do I get the shortened text and not the "real" text within the EraseItem draw handler?
#Override
public void handleEvent( final Event event ) {
final TableItem ti = (TableItem) event.item;
final int index = event.index;
final GC gc = event.gc;
if( ti == null || currentSwyt.isEmpty() ) {
return;
}
final String text = ti.getText( index );
if( !text.contains( currentSwyt ) ) {
return;
}
// search text is contained
final String[] parts = text.split( currentSwyt );
final int swytWidth = gc.stringExtent( currentSwyt ).x;
// calculate positions, must be relative to the text's start
int x = event.x; // THIS IS THE PROBLEM: event.x is not enough!
final int[] pos = new int[parts.length - 1];
for( int i = 0; i < parts.length - 1; i++ ) {
x += gc.stringExtent( parts[i] ).x;
pos[i] = x;
}
final Color red = event.display.getSystemColor( SWT.COLOR_RED );
final Color oldBackground = gc.getBackground();
gc.setBackground( red );
for( int j = 0; j < pos.length; j++ ) {
gc.fillRectangle( pos[j], event.y, swytWidth, event.height );
}
gc.setBackground( oldBackground );
event.detail &= ~SWT.BACKGROUND;
}
I think it would be quite useful for you to have a look at TableViewer and StyledCellLabelProvider. That will make your task a lot easier I think considering the kind of text formatting you require. Since the drawing is than completely handled by the label provider, you can avoid these pesky margin issues.
As for almost all SWT Widgets, this might be OS dependent. The actual "drawing" of the table is done using OS resources.
However, it might be worth having a look at TableItem#getTextBounds(int).
It returns a Rectangle that should reflect the margins.
For your bonus question: I have never seen the text being shortened automatically in my applications. In fact I had a hard time doing this myself. But that might as well be OS dependent, since I use Linux.