Java trouble with threads - java

I am trying to create a slot machine in java. In this slot machine I have completed the basic beginning of the project. I have the animators that lands on a random space (cherry, blank, seven, etc), the background, buttons to start and bet in the opening, however I have to figure out the ending of the slot; how to make the results of the slot machine appear without the user clicking a button. To do this I figure the best way is to dive into the realm of threads. However when I tried to create a simple thread, the animators stopped working and when I took the thread out, the animators did work. It is quite the conundrum.
Here is some of the code if that helps explanation :
public class SlotMachineOpeningGraphic extends JPanel implements Runnable
{
JLayeredPane layeredPane= new JLayeredPane ();
JFrame frame = new JFrame();
public Thread thread;
public volatile boolean running = false;
Player plyr = new Player ();
public static final long startTime = System.currentTimeMillis ();
JLabel numberBet = new JLabel ("" + plyr.getBet()); //things that change on JFrame
JLabel numberAccount = new JLabel (""+ plyr.getAccount ());
JButton betButton = new JButton ("Bet ++");
JButton playAgain = new JButton ("Start");
public SlotMachineOpeningGraphic()
{
layeredPane.setPreferredSize(new Dimension(750, 460));//changes size to image with border for buttons
//andlabels
ImageIcon bG = new ImageIcon ("/Users/Documents/slotmachine.png");//background file
JLabel backGround = new JLabel (bG);
backGround.setBounds (70,0, bG.getIconWidth(), bG.getIconHeight());//won't display if you do not set bounds
layeredPane.add (backGround, new Integer (0));//add to first layer
/*add buttons and labels to give user options
* and information, placed in layer 2 */
playAgain.setBounds (110,420, 100, 25);
layeredPane.add (playAgain, new Integer (2));
playAgain.addActionListener (new Start());
betButton.setBounds (320,420, 100, 25);
layeredPane.add (betButton, new Integer (2));
betButton.addActionListener (new SlotBB ());
JButton mainMenu = new JButton ("Main Menu");
mainMenu.setBounds (520,420, 100, 25);
layeredPane.add (mainMenu, new Integer (2));
long checkTime = System.currentTimeMillis ();
System.out.println ("Total execution time : " + (checkTime - startTime));
JLabel bet = new JLabel ("Bet:");
bet.setBounds (620, 320, 100, 30);
Font font = new Font ("Corsiva Hebrew",bet.getFont().getStyle(),30); //desired font & size
bet.setFont (font);
layeredPane.add (bet, new Integer (2));
numberBet.setBounds (620, 340, 100, 30);
layeredPane.add (numberBet, new Integer (2));
numberBet.setFont (font);
JLabel account = new JLabel ("Account: ");
account.setBounds (5, 320, 150, 30);
account.setFont (font);
layeredPane.add (account, new Integer (2));
numberAccount.setBounds (5, 340, 150, 30);
numberAccount.setFont (font);
layeredPane.add (numberAccount, new Integer (2));
add(layeredPane);
JComponent newContentPane = layeredPane;
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
frame.setBackground (Color.white);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public void run ()
{
try {
Thread.sleep (20);
System.out.println ("works");
}
catch (Exception e) {
System.out.println ("doesn't work");
}
}
class Start extends JPanel implements ActionListener
{
public void actionPerformed (ActionEvent event)
{
SlotAnimator a0 = new SlotAnimator (40);
a0.setBounds(155, 85, 100, 90);
layeredPane.add (a0, new Integer (1));
SlotAnimator a1 = new SlotAnimator (85);
a1.setBounds(320, 85, 100, 90);
layeredPane.add (a1, new Integer (1));
SlotAnimator a2 = new SlotAnimator (135);
a2.setBounds(470, 85, 100, 90);
layeredPane.add (a2, new Integer (1));
playAgain.setText ("play again?");
hearSound();
thread = new Thread (new SlotMachineOpeningGraphic ());
thread.start ();
}
}
public static void main (String [] args)
{
new SlotMachineOpeningGraphic();
}
}
Any suggestions on an approach? It would be greatly appreciated!

#HFOE is right about using javax.swing.Timer, which manages its own thread to generate periodic GUI events in a safe way. You may also want to look at adopting the Model-View-Controller pattern, exemplified here.

This is at least one of your mistakes:
thread = new Thread(new SlotMachineOpeningGraphic());
You are creating a new SlotMachineOpeningGraphic object, one that is completely distinct from the original one. Don't do this. If you had to use a SlotMachineOpeningGraphic object here, then you should use a reference to the original class that already exists and holds the Start private inner class, such as:
thread = new Thread(SlotMachineOpeningGraphic.this);
So this isn't a "threading" issue per se, but rather a reference issue -- you use the wrong reference as the Runnable for your thread.
But I strongly advise you against using your GUI classes for ActionListeners, OtherListeners or Runnables as you're asking the class to do too much. Better to use an anonymous inner class or a separate stand-alone class.

You could try to use a Future or Runnable classes for doing the processing, and retriving their result as soon as they finish. Just make sure to put those threads in a Thread pool!

Related

Resizing Components and Font with MigLayout

i'm pretty new to Layout Managers and i have absolutely no idea how to resize the Font-Size automatically with the MigLayout Manager. I have already managed to resize the components with the grow and fill constraint, but I don't seem to get the font-size to change with the size of the components. How do i do this?
Here my few code lines:
public class Projekte {
public Projekte()
{
main();
}
public static void main() {
JFrame projekte = new JFrame();
projekte.setBounds(100, 100,1080,1900);
projekte.setExtendedState(Frame.MAXIMIZED_BOTH);
projekte.setTitle("Testframe");
projekte.getContentPane().setBackground(new Color(255,255,255));
projekte.getContentPane().setLayout(new MigLayout("", "[][][][][][grow,fill][][][][]", "[][][][][][][][][][][grow,fill][][]"));
JLabel lblTest = new JLabel("Test");
projekte.getContentPane().add(lblTest, "cell 4 10,alignx trailing");
JTextField textField = new JTextField();
projekte.getContentPane().add(textField, "cell 5 10");
textField.setColumns(10);
JLabel lblTest_2 = new JLabel("Test_2");
projekte.getContentPane().add(lblTest_2, "cell 6 10,alignx trailing");
JTextField textField_2 = new JTextField();
projekte.getContentPane().add(textField_2, "cell 7 10");
textField_2.setColumns(10);
JLabel lblTest_3 = new JLabel("Test_3");
projekte.getContentPane().add(lblTest_3, "cell 4 11,alignx trailing");
JTextField textField_3 = new JTextField();
projekte.getContentPane().add(textField_3, "cell 5 11");
textField_3.setColumns(10);
}
}
I think it is quite easy, but I don't seem to find the solution, maybe you can help.
Font have attributes, but any of them relate to layout - you can manually scale font with some parameter using deriveFont(float size)
- creates a new Font object by replicating the current Font object and applying a new size to it.
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = screenSize.width;
float scale = screenWidth/1000;
label.getFont().deriveFont(scale);

How do I scale JXMonthView?

Hi everyone reading this.
I am currently developing a program, that should run well displayed in different resolutions and thus has a scaling factor.
There is ne component, that I cannot find a solution for scaling for:
The JXDatePicker and its JXMonthView.
What I tried:
final JXDatePicker datePicker = new JXDatePicker(new Date());
final JXMonthView monthView = datePicker.getMonthView();
monthView.setBounds(hauptFrame.getSize().width / 2 - (100*ViewerDefaults.SZ_INCR), (165*ViewerDefaults.SZ_INCR), (200*ViewerDefaults.SZ_INCR), (200*ViewerDefaults.SZ_INCR));
monthView.setSize(monthView.getWidth() * ViewerDefaults.SZ_INCR, monthView.getHeight() * ViewerDefaults.SZ_INCR);
monthView.setPreferredColumnCount(1);
monthView.setPreferredRowCount(1);
monthView.setTraversable(true);
monthView.setZoomable(true);
datePicker.setSize(datePicker.getWidth() * 2, datePicker.getHeight() * 2);
ViewerDefaults.SZ_INCR is the scaling factor and would replace the 2 in the last line, if working.
I added the setPreferredColumnCount(1) and setPreferredRowCount(1) as I tried setting the size of the JXMonthview before, but I ended up having 4 months displayed next to each other, whereas I just wanted a single, larger displayed month.
Can you help and show me a way to enlarge the display of only on month?
EDIT:
I translated everything into using Layout Managers. The problematic behaviour remains: The month displayed is not scaled up, but simply displayed in the center. To give some more insight to the code I put the whole method here as follows(size is set earlier by Toolkit.getDefaultToolkit().getScreenSize();):
private static JPanel licBorrowPanel = null;
licBorrowPanel = new JPanel();
licBorrowPanel.setBounds(0, 20, size.width, size.height-20);
licBorrowPanel.setVisible(false);
licBorrowPanel.setBackground(Color.WHITE);
public static void licenceBorrowDialog() {
licBorrowPanel.setSize(new Dimension(hauptFrame.getSize().width, hauptFrame.getSize().height));
licBorrowPanel.setBackground(Color.WHITE);
licBorrowPanel.setLayout(new BorderLayout());
licBorrowPanel.setVisible(true);
//Create upper part of licBorrowPanel
JPanel licBorrowTop = new JPanel();
licBorrowTop.setLayout(new BoxLayout(licBorrowTop, BoxLayout.Y_AXIS));
// Label Titel
JLabel labelTitel = new JLabel("License borrwing");
labelTitel.setHorizontalAlignment(JLabel.CENTER);
labelTitel.setFont(ViewerDefaults.DEF_LABEL_FONT);
licBorrowTop.add(labelTitel);
// Header Calendar
JLabel calendarTitle = new JLabel("Please select a date", SwingConstants.LEFT);
calendarTitle.setHorizontalAlignment(JLabel.CENTER);
calendarTitle.setFont(ViewerDefaults.DEF_ROW_FONT);
licBorrowTop.add(calendarTitle);
licBorrowPanel.add(licBorrowTop, BorderLayout.PAGE_START);
//Create central part of licBorrowPanel
JPanel licBorrowCenter = new JPanel();
licBorrowCenter.setLayout(new BoxLayout(licBorrowCenter, BoxLayout.Y_AXIS));
// Label selectedDate
final JLabel labelSelectedDate = new JLabel("<HTML><BODY> </HTML></BODY>");
labelSelectedDate.setHorizontalAlignment(JLabel.CENTER);
labelSelectedDate.setFont(ViewerDefaults.DEF_LIC_FONT);
labelSelectedDate.setText("<HTML><BODY><b>Some Text</HTML></BODY>");
// Calendar
final JXDatePicker datePicker = new JXDatePicker(new Date());
final JXMonthView monthView = datePicker.getMonthView();
monthView.setPreferredColumnCount(1);
monthView.setPreferredRowCount(1);
monthView.setZoomable(true); //Removing this results in several Columns and Rows being displayed.
// Set selection to "in two days" as default
Date newDate = monthView.getSelectionDate();
newDate.setDate(newDate.getDate()+2);
datePicker.addActionListener(new ActionListener() {
//...
});
licBorrowCenter.add(monthView, BorderLayout.CENTER);
licBorrowCenter.add(labelSelectedDate, BorderLayout.CENTER);
// Footer Calendar
JLabel calendarSubTitle = new JLabel("<HTML><BODY><CENTER>Some other Text.</CENTER></HTML></BODY>", SwingConstants.LEFT);
calendarSubTitle.setFont(ViewerDefaults.DEF_FONT);
calendarSubTitle.setHorizontalAlignment(JLabel.CENTER);
calendarSubTitle.setFont(ViewerDefaults.DEF_ROW_FONT);
calendarSubTitle.setForeground(Color.RED);
licBorrowCenter.add(calendarSubTitle, BorderLayout.CENTER);
licBorrowPanel.add(licBorrowCenter);
//Create lower part of licBorrowPanel
JPanel licBorrowBottom = new JPanel();
licBorrowBottom.setLayout(new BorderLayout());
// Button OK
JButton buttonLicBorrowOK = new JButton("OK");
buttonLicBorrowOK.setFont(ViewerDefaults.DEF_LIC_FONT);
licBorrowBottom.add(buttonLicBorrowOK, BorderLayout.LINE_START);
// Button Return
JButton buttonLicReturn = new JButton("Return");
buttonLicReturn.setFont(ViewerDefaults.DEF_LIC_FONT);
licBorrowBottom.add(buttonLicReturn, BorderLayout.CENTER);
// Button Cancel
JButton buttonLicBorrowCancel = new JButton("Cancel");
buttonLicBorrowCancel.setFont(ViewerDefaults.DEF_LIC_FONT);
licBorrowBottom.add(buttonLicBorrowCancel, BorderLayout.LINE_END);
licBorrowPanel.add(licBorrowBottom, BorderLayout.PAGE_END);
// Update licBorrowPanel
licBorrowPanel.update(licBorrowPanel.getGraphics());
// several action listeners for buttons eluded..
}
"hauptframe" is the parent JFrame.
An additional problem occurred, but I think this will be solved once the JXMonthView is displayed as wanted: The licBorrowBottom is not displayed.
I hope this clarifies the problem and helps helping :)

Components get squished in JPanel and JFrame

I'm trying to create a GUI window for the user to enter some information for my program. But it seems like no matter how I change the sizes or the locations, all of my components are squished in far smaller than what I want. Could someone please point out what I am missing?
Here's what I tried:
JFrame inputFrame = new JFrame();
JPanel panel = new JPanel();
inputFrame.setTitle("Create Event");
inputFrame.setSize(500,400);
JTextField eventName = new JTextField("Untitled event");
JTextField eventStart = new JTextField();
JTextField eventEnd = new JTextField();
JButton save = new JButton("Save");
JLabel selectedDate = new JLabel(MyCalendarTester.currentMonth + 1 + "/" + selectedDay + "/" + MyCalendarTester.currentYear);
selectedDay = null;
panel.setSize(450,300);
eventName.setBounds(10, 10, 600, 50);
panel.add(eventName);
selectedDate.setBounds(10, 20, 50, 20);
panel.add(selectedDate);
panel.add(eventStart);
eventStart.setBounds(100, 20, 50, 20);
panel.add(eventEnd);
eventEnd.setBounds(175, 20, 50, 20);
panel.add(save);
save.setBounds(250, 20, 60, 30);
inputFrame.add(panel);
inputFrame.setVisible(true);
The default layout manager for a JPanel is the FlowLayout. The FlowLayout will display components at their preferred size, which is the way the component should be displayed.
You should not attempt to give the component a random size because you don't know what the best size for the component should be based on Font, OS etc.
When you create a JTextField you can use:
JTextField textField = new JTextField(10);
The value 10 will allow the text field to give itself a reasonable preferred size.
The JLabel and JButton size will be determined by the text of the component.

Simple way to add window to system tray [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How can I put my Java program in the system tray?
I am making a notification system in java, I want the program to show up in the system tray, instead of on the task bar, I have tried:
notification.setExtendedState(JFrame.ICONIFIED);
Not only does this not work, but it lags the heck otta my computer
Current Code:
public static void notify(String line1, String line2, String imagepath, int style){
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int width = gd.getDisplayMode().getWidth();
int swidth = width - 320;
JFrame notification = new JFrame();
JPanel main = new JPanel(new FlowLayout(FlowLayout.RIGHT));
main.setLayout( new GridLayout( 2 , 1 ) );
JLabel notifyline1 = new JLabel();
notifyline1.setText(line1);
notifyline1.setFont(new Font("Minecraft",1 , 16));
notifyline1.setForeground(new Color(242, 238, 17));
main.add(notifyline1);
JLabel notifyline2 = new JLabel();
notifyline2.setText(line2);
notifyline1.setFont(new Font("Minecraft",1 , 12));
notifyline1.setForeground(Color.black);
main.add(notifyline1);
notification.add(main);
notification.setExtendedState(JFrame.ICONIFIED);
notification.setSize(new Dimension(320,64));
notification.setLocation(swidth, 0);
notification.setUndecorated(true);
notification.setVisible(true);
}
ALSO, to kill 2 birds with one stone
is there a way to color a jlabel, tried
label1.setForegroundColor(new Color(100, 100, 100));
Java has TrayIcon class which can be used to minimize application to SystemTray.You can see the working example here.

How to make Arrays of my JButton/ActionListeners

I'm doing a project for school and we need to create a program with many JButtons, ActionListeners, images, etc. I have created a class with many individual ActionListeners and JButtons, but how can I change this into an array of buttons rather than creating them all individually?
This is my code...
public class Selectie extends JFrame{
private JButton keeper, verdediger, verdediger1, verdediger2;
public void initGUI() {
keeper = new JButton("1. "+""+" Kenneth Vermeer");
Cursor cur = keeper.getCursor();
keeper.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
keeper.setBounds(20, 50, 186, 12);
keeper.setFocusable(false);
keeper.setBorderPainted(false);
keeper.setContentAreaFilled(false);
keeper.setFont(new Font("Arial",Font.PLAIN,17));
keeper.setForeground(Color.WHITE);
keeper.setActionCommand(Vermeer);
verdediger = new JButton("2. "+""+" Gregory van der Wiel");
Cursor cur1 = verdediger.getCursor();
verdediger.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
verdediger.setBounds(20, 70, 215, 17);
verdediger.setFocusable(false);
verdediger.setBorderPainted(false);
verdediger.setContentAreaFilled(false);
verdediger.setFont(new Font("Arial",Font.PLAIN,17));
verdediger.setForeground(Color.WHITE);
verdediger.setActionCommand(Gregory);
verdediger1 = new JButton("3. "+""+" Toby Alderweireld");
Cursor cur2 = verdediger1.getCursor();
verdediger1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
verdediger1.setBounds(20, 95, 188, 17);
verdediger1.setFocusable(false);
verdediger1.setBorderPainted(false);
verdediger1.setContentAreaFilled(false);
verdediger1.setFont(new Font("Arial",Font.PLAIN,17));
verdediger1.setForeground(Color.WHITE);
verdediger1.setActionCommand(Alderweireld);
verdediger2 = new JButton("4. "+""+" Jan Vertonghen");
Cursor cur3 = verdediger2.getCursor();
verdediger2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
verdediger2.setBounds(20, 120, 174, 17);
verdediger2.setFocusable(false);
verdediger2.setBorderPainted(false);
verdediger2.setContentAreaFilled(false);
verdediger2.setFont(new Font("Arial",Font.PLAIN,17));
verdediger2.setForeground(Color.WHITE);
verdediger2.setActionCommand(Vertonghen);
SelectieController s1 = new SelectieController(keeper,verdediger,verdediger1,verdediger2);
keeper.addActionListener(s1);
verdediger.addActionListener(s1);
verdediger1.addActionListener(s1);
verdediger2.addActionListener(s1);
}
}
Without doing all the work, you need to do something like this (you can fill in the blanks - it is your homework after all...)
// create the array
JButton[] buttons = new JButton[10];
// Repeat for each button...
for (int i=0;i<buttons.length;i++){
// create the button
JButton button = new JButton("label");
// set the button properties...
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button.setBounds(20, 95, 188, 17);
button.setFocusable(false);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
// etc.
// Assign the listener
button.addActionListener(s1);
// Add the button to the array
buttons[i] = button;
}

Categories