I am trying to change the JCalendar component background color from the component properties itself with no success.
While changing the foreground color from the component proprieties is working fine.
I also tried menuCalendar.setBackground(new Color(135,239,251)) with no success.
Can anyone help?
Setting the background color for JCalendar is surprisingly complicated. There is one convenience method which allows to change part of the calendar's background. You could see if this does what you want first: menuCalendar.setDecorationBackgroundColor(new Color(135,239,251));
This probably won't do what you want. Changing the color of the background behind the day buttons and the colors of the buttons themselves can be changed with the following code. It has to be done this way as JCalendar uses native Swing components which are nested in one another and convenience methods seem to be lacking:
for (int i = 0; i < menuCalendar.getComponentCount(); i++) {
if (menuCalendar.getComponent(i) instanceof JDayChooser) {
JDayChooser chooser = ((JDayChooser) menuCalendar.getComponent( i ) );
JPanel panel = (JPanel) chooser.getComponent(0);
// the following line changes the color of the background behind the buttons
panel.setBackground(Color.BLACK);
// the for loop below changes the color of the buttons themselves
for (int y = 0; y < panel.getComponentCount(); y++) {
panel.getComponent(y).setBackground(Color.BLACK);
}
break; // leave the for loop, we're done
}
}
Related
The simple version is that I'm drawing Graphics2D 60 times a second on a JPanel and it uses the drawstring method to create a bunch of labels. How would I go about making so I can click on those labels and have something happen?
Explanation: As it currently stands I have a system setup that says for every object in the world draw a string to the side (So I can see a list of all objects in the world). This is done with a for loop and the Graphics2D drawstring method.
The JPanel is being updated 60 times a second so this is being redrawn 60 times a second. I want to be able to click on these object labels so I can select the items, how would I go about turning them into buttons?
I messed around with JButton for awhile but it didn't seem to do me any good because whenever I added it the JPanel would go blank and only the button would render (Plus it didn't render to the right size).
More Details:
I use a
for(int I=0; I < sceneObjects.size(); I++) {
}
loop to grab every object in an object ArrayList. Each object has a String variable "Name". Before the loop class I sent an int called YPosition, and for every object the YPosition goes up by 20 so that the labels don't all stack on top of each other. I'm using the g2d.DrawString method to achieve this. But I need to be able to select the object labels.
I apologize if I forgot something in my question, let me know.
For those who are curious, the code looks exactly like this (Can't be compiled as is):
g2d.setFont(new Font("Arial", Font.PLAIN, hierarchyWidth / 26));
g2d.setColor(Color.black);
int oYPos = 20;
// For every object in existence
for(int i=0; i < engine.sceneObjects.activeObjects.size(); i++) {
GameObject theObject = engine.sceneObjects.activeObjects.get(i);
// If the scrollbar is within range of the hierarchy
// (Based on HierarchyHeight so that it's resolution friendly)
if(oYPos >= hierarchyScroll && oYPos < hierarchyScroll + hierarchyHeight) {
// If the object has no parent
if(theObject.transform.parent == null) {
g2d.drawString(theObject.name, hierarchyPosition.x + 5, hierarchyPosition.y + oYPos);
} else { // If the object has a parent
}
}
oYPos += 20;
}
// Track the last oYPos so that the scrollbar can adjust itself accordingly
lastOYPos = oYPos;
My guess would be some sort of class create for each of these labels and a Boolean stored called isSelected, and then rendering the label according to the class, but this seems a bit more complicated than I'd like to do
I have met a serious problem with my Java swing.
This is how I initialize my chart, everything seems fine now, xyChartPanel is declared as a JPanel in the field, I initialize it with the xyChart I just created. When this step is done, I am okay to see the chart (painted to xyChartPanel) centered to the JPanel I am writing code on, see add(xyChartPanel, BorderLayout.CENTER);.
private void initXYChart() {
// Create Chart
xyChart = new XYChartBuilder().width(800).height(800).xAxisTitle(xColName).yAxisTitle("Y").build();
// Customize Chart
xyChart.getStyler().setLegendPosition(LegendPosition.InsideNE);
xyChart.getStyler().setAxisTitlesVisible(true);
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Line);
double[] yCoordArray = new double[xCoordArray.length];
// Loop through the series
for (int i = 0; i < yCoordinates.size(); i++) {
List<Double> yCoordOneSeries = yCoordinates.get(i);
// Convert list to array
for (int j = 0; j < yCoordArray.length; j++) {
yCoordArray[j] = yCoordOneSeries.get(j);
}
xyChart.addSeries(yColNames.get(i), xCoordArray, yCoordArray);
}
xyChartPanel = new XChartPanel<>(xyChart);
add(xyChartPanel, BorderLayout.CENTER);
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Area);
add(xyChartPanel, BorderLayout.CENTER);
}
Now the problem comes, I don't want my chart to be unchanged all the time, actually I want to change the style of my chart responded to my action on the radio buttons.
I just wrote the updateChartPanelStyle(JRadioButton styleButton) method that takes
private void updateChartPanelStyle(JRadioButton styleButton) {
String style = styleButton.getText();
if (styleButton.isSelected()) {
System.out.println(style);
switch (style) {
case "Line":
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Line);
break;
case "Area":
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Area);
break;
case "Scatter":
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Scatter);
}
xyChartPanel = new XChartPanel<>(xyChart);
add(xyChartPanel, BorderLayout.CENTER);
}
}
See in this method, I changed the style of xyChart I initialized in the last function, and reinitialize the xyChartPanel, then add the updated xyChartPanel to the working panel. Interestingly, I didn't see any change in my GUI. I thought this might be a problem with my xyChart whose style could not be changed afterward. But this is not really the case.
Even if I "removed" xyChartPanel with this.remove(xyChartPanel);, the GUI doesn't seems to be changed.
This is really weird, what should I do now?
Every time you add/remove components to swing dynamically, you need to call revalidate(); and then repaint(); on your JPanel (or JFrame if you're adding it straight to that).
I have a GUI, from this GUI I choose an input file with the dimensions of a Booking system(new GUI) If the plane has 100 seats the GUI will be for example 10x10, if the plane has 200 seats it will be 10x20, all the seats are going to be buttons, and should store passenger information on them if they are booked.Also a booked seat shall not be booked again.
The question is the dimensions of the GUI will change according to the seat numbers and orientation, which means in one version there can be lots of buttons on another less, also more seats means the GUI will be longer or wider maybe 10 cm x 10 cm or 10 cm x 20 cm, or 15 cm x 25 cm...
I am thinking to do this with a for loop but I dont want to put buttons out of the GUI.I dont know how can I add a button next to the other button arbitrarily. I always used Eclipse Window Builder for building GUIs but I guess I need to write this one on my own... can someone help me?Some hints?Thanks for your time!
Try something like this:
// The size of the window.
Rectangle bounds = this.getBounds();
// How many rows of buttons.
int numOfRows = 100;
// How many buttons per row.
int numOfColumns = 50;
int buttonWidth = bounds.width / numOfRows;
int buttonHeight = bounds.height / numOfColumns;
int x = 0;
int y = 0;
for(int i = 0; i < numOfColumns; i++){
for(int j = 0; j < numOfRows; j++){
// Make a button
button.setBounds(x, y, buttonWidth, buttonHeight);
y += buttonHeight;
}
x += buttonWidth;
}
This will make all the buttons fit inside of your window.
Here's a link on rectangles, they come in pretty handy when doing things like this.
http://help.eclipse.org/helios/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fswt%2Fgraphics%2FRectangle.html
Also, you can still use windowbuilder, infact I recommend you do. It really helps you to visualize the dimensions you want. AND you can also create stuff (buttons, lists, dropdowns... etc) manually with code and, assuming you put the variables where WindowBuilder would, it will still display them in the 'design' tab.
Hope this helps!
EDIT: I was kinda vague on how to make buttons using a loop
To make buttons with a loop you will need a buffer (to store a temporary button long enough to add to a list) and... a list :D.
This is how it should look:
Outside loop:
// The list to store your buttons in.
ArrayList<Button> buttons = new ArrayList<Button>();
// The empty button to use as a buffer.
Button button;
Inside loop (where the '//Make a button' comment is):
button = new Button(this, SWT.NONE);
buttons.add(button);
Now you have a list of all the buttons, and can easily access them and make changes such as change the buttons text like so;
buttons.get(indexOfButton).setText("SomeText");
EDIT:
Seeing as you're new to swt (and I couldn't get awt/JFrame to work) here's the full code.
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class ButtonTest extends Shell {
/**
* Launch the application.
* #param args
*/
// Code starts here in main.
public static void main(String args[]) {
try {
Display display = Display.getDefault();
// Creates a window (shell) called "shell"
ButtonTest shell = new ButtonTest(display);
// These two lines start the shell.
shell.open();
shell.layout();
// Now we can start adding stuff to our shell.
// The size of the window.
Rectangle bounds = shell.getBounds();
// How many rows of buttons.
int numOfRows = 5;
// How many buttons per row.
int numOfColumns = 3;
int buttonWidth = bounds.width / numOfRows;
int buttonHeight = bounds.height / numOfColumns;
Button button;
int x = 0;
int y = 0;
for(int i = 0; i < numOfColumns; i++){
for(int j = 0; j < numOfRows; j++){
button = new Button(shell, SWT.NONE);
button.setBounds(x, y, buttonWidth, buttonHeight);
x += buttonWidth;
}
x = 0;
y += buttonHeight;
}
// This loop keeps the shell from killing itself the moment it's opened
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Create the shell.
* #param display
*/
public ButtonTest(Display display) {
super(display, SWT.SHELL_TRIM);
createContents();
}
/**
* Create contents of the shell.
*/
protected void createContents() {
setText("SWT Application");
setSize(800, 800);
}
#Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
Also, I made a little typo in my nested loop (and forgot to reset the x value to 0 after each row). It's fixed in this edit.
Also you will need to import swt for this to work.
Go here: http://www.eclipse.org/swt/ and download the latest version for your operating system, then go in eclipse, right click your project > Build Path > configure Build Path > Libraries tab > Add external JAR's > find the swt file you downloaded and click.
Sorry for such a long answer, hope it helps :D
Start with a GridLayout. Each time you need to change the seat layout, reapply the GridLayout.
Ie, if you need 100 seats, use something like, new GridLayout(20, 10)...
Personally, I'd use a GridBagLayout, but it might be to complex for the task at hand
Its a little more difficult to add/rmove new content. I would, personally, rebuild the UI and reapply the model to it.
As for the size, you may not have much control over it, as it will appear differently on different screens. Instead, you should provide means by which you can prevent the UI from over sizing the screen.
This is achievable by placing the seating pane within a JScrollPane. This will allow the seating pane to expand and shrink in size without it potentially over sizing on the screen
Take a look at
Creating a UI with Swing
Using Layout Managers
A Visual Guide to Layout Managers
I have a 9x9 panel, which is panel1[][]
each panel has a JLabel, so label1[][]
and I add each label to the panel in for loop:
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
label[y][x] = new Grid(x, y);
panel1[y][x].add(label[y][x]);
}
}
The main goal is to be able to add a addUndoableEditListener() to each of these JLabels.
Users will select a number(int) to place in the JLabel, I want them to be able to undo/redo their selection, by clicking the undo/redo button.
I tried:
UndoManager manager = new UndoManager();
label1.addUndoableEditListener(manager);
However I saw that apprently you cannot add "UndoableEditListener" to JLabels. (Right?)
I saw some examples where you could add "UndoableEditListener" to JTextPane, so I though maybe I could create a JTextPane pane [9][9], and add a textpane to each of the JLabels(which are added to the JPanel). So this would solve the problem of UndoableEditListener.
Does this seem logical? I would really appreciate an easier approach to this, all suggestions welcome : )
I'm just having some problem with adding the UndoableEditListener to the components.
(I would prefer to keep the JLabel, since I need to be able to change the background color feature, otherwise is there a better way??)
Thanks.
It looks like you don't really want a JLabel. If you want it to be editable (and undoable), why not a JTextField?
A JTextField can have its background color changed as well as a JLabel:
JTextField tf = new JTextField();
tf.setColor(Color.RED);
The scenario: I have a UI that contains a JPanel (call it topGrid) with a grid layout in a JFrame at the top level. Within topGrid, I have placed another JPanel (midGrid) with grid layout. Inside midGrid, is another JPanel (bottomGrid) that has a JLabel that I populate with images depending on an array and what their instance is within that array.
The goal: I would like the topGrid to center its view on a specific object found in bottomGrid. (Picture a game that as the player icon moves, the game's grid moves to center on that icon and also when the game is started it is already centered for the user.)
I've considered getting the Point from bottomGrid and trying to pass it over to topGrid but doesn't seem to pull the correct information. The only way i know to find where the player is, is to iterate through all the components and check instances. this would have to be done once for the topGrid and again for midGrid to find the player at bottomGrid. then pass the Point data. Then use setLocation() on the appropriate JPanel minus the distance from the center.
Has anyone else tried this and have a more effective or elegant way to go about it? What other options could I explore?
Thanks for any feedback.
Creating the grid within topGrid's JPanel:
public void createTopGrid()
{
int rows = galaxy.getNumRows();
int columns = galaxy.getNumColumns();
pnlGrid.removeAll();
pnlGrid.setLayout(new GridLayout(rows, columns));
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
Position pos = new Position(galaxy, row, col);
Sector sector = galaxy.getSector(pos);
GalaxySector sectorUI = new GalaxySector(sector);
pnlGrid.add(sectorUI);
}
}
}
Creating the grid within midGrid's JPanel:
public void createOccupantIcons()
{
pnlGridOccupants.removeAll();
Occupant[] occs = sector.getOccupantsAsArray();
for ( Occupant occ : occs )
{
GalaxyOccupant occupant = new GalaxyOccupant(occ, sector);
pnlGridOccupants.add(occupant);
}
}
The Image icons for each occupant in the midGrid are pulled from an IconRep String in the model in the bottomGrid class' JPanel and added into a JLabel as needed in FlowLayout.
For visual reference:
Where green square is topGrid JPanel, red squares are midGrid JPanel, and the black square is the bottomGrid JPanel with the white circle for the player image inside a JLabel. The blue circle represents a viewport the user will see the game through and is where I want the player icon to be centered to. Currently the user can move the grid's using very inelegant buttons in the area around the viewport. That might be sufficient but at the start of the game the player has to move the grid around until they can locate their icon.
You might also look at JScrollNavigator, examined here. It would allow you to navigate on a thumbnail image of your entire world, seen at full size in an adjacent scroll pane.
Off the top of my head, I would store all the references you want to in some kind of model.
You could use this model to update the views based on selection requirements.
This allows the you to centralise the logic for finding and updating the elements without knowing or caring out the other UI elements