How do I Check Winner In connect 4 Diagonally? [duplicate] - java

This question already has answers here:
Connect 4 check for a win algorithm
(6 answers)
Closed 6 years ago.
So i am having problem checking the winner diagonally in a game called connect 4. I didn't have any problem checking vertically and horizontally. So.. Can u please help me check diagonally?
Code so far:
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
public class connectFourDesign extends JPanel {
private static final long serialVersionUID = 1L;
// Welcome Screen
private JLabel lblWelcome;
// Buttons for Welcome Screen
private JButton playButton;
private JButton helpButton;
private JButton quitButton;
// Game Modes
private JButton onePlayer;
private JButton twoPlayer;
// Go Back Button
private JButton goBack;
private JButton clickMeOne;
private JButton clickMeTwo;
private JButton clickMeThree;
private JButton clickMeFour;
private JButton clickMeFive;
private JButton clickMeSix;
private JButton clickMeSeven;
// Grid xSize,ySize and 2D Array
private int ysize = 7;
private int xsize = 8;
private JButton[][] slots;
public static void main(String[] args) {
JFrame frame = new JFrame(" Connect Four ");
frame.setSize(500, 500);
frame.getContentPane().add(new connectFourDesign());
frame.setVisible(true);
frame.setResizable(false);
}
public connectFourDesign () {
setBackground(Color.black);
lblWelcome = new JLabel (" Connect 4 ", SwingConstants.CENTER);
lblWelcome.setFont(new Font("Astron Boy Rg", Font.ITALIC, 90));
lblWelcome.setForeground(Color.white);
add(lblWelcome);
lblWelcome.setVisible(true);
playButton = new JButton (" Play ");
playButton.setFont(new Font("Astron Boy Rg", Font.ITALIC, 75));
playButton.setBackground(Color.black);
playButton.setForeground(Color.GREEN);
add(playButton);
playButton.setVisible(true);
playButton.addActionListener(new playButtonListener());
onePlayer = new JButton (" 1 Player ");
onePlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 55));
onePlayer.setBackground(Color.black);
onePlayer.setForeground(Color.GREEN);
add(onePlayer);
onePlayer.setVisible(false);
onePlayer.addActionListener(new onePlayerButtonListener());
twoPlayer = new JButton (" 2 Player ");
twoPlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 55));
twoPlayer.setBackground(Color.black);
twoPlayer.setForeground(Color.GREEN);
add(twoPlayer);
twoPlayer.setVisible(false);
twoPlayer.addActionListener(new twoPlayerButtonListener());
helpButton = new JButton ( " Help ");
helpButton.setFont(new Font("Astron Boy Rg", Font.ITALIC, 75));
helpButton.setBackground(Color.black);
helpButton.setForeground(Color.magenta);
add(helpButton);
helpButton.setVisible(true);
helpButton.addActionListener(new helpListener());
quitButton = new JButton ( " Quit ");
quitButton.setFont(new Font("Astron Boy Rg", Font.ITALIC, 75));
quitButton.setBackground(Color.black);
quitButton.setForeground(Color.orange);
add(quitButton);
quitButton.setVisible(true);
quitButton.addActionListener(new CloseListener());
goBack = new JButton ( " Go Back ");
goBack.setFont(new Font("Astron Boy Rg", Font.ITALIC, 60));
goBack.setBackground(Color.black);
goBack.setForeground(Color.BLUE);
add(goBack);
goBack.setVisible(false);
goBack.addActionListener(new goBackButtonListener());
clickMeOne = new JButton ();
clickMeOne.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
clickMeOne.setBackground(Color.gray);
clickMeOne.setForeground(Color.CYAN);
clickMeOne.setName("clickMeOne");
add(clickMeOne);
clickMeOne.setVisible(false);
clickMeOne.addActionListener(new clikMeOneButtonListener());
clickMeTwo = new JButton ();
clickMeTwo.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
clickMeTwo.setBackground(Color.gray);
clickMeTwo.setForeground(Color.CYAN);
clickMeTwo.setName("clickMeTwo");
add(clickMeTwo);
clickMeTwo.setVisible(false);
clickMeTwo.addActionListener(new clikMeOneButtonListener());
clickMeThree = new JButton ();
clickMeThree.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
clickMeThree.setBackground(Color.gray);
clickMeThree.setForeground(Color.CYAN);
clickMeThree.setName("clickMeThree");
add(clickMeThree);
clickMeThree.setVisible(false);
clickMeThree.addActionListener(new clikMeOneButtonListener());
clickMeFour = new JButton ();
clickMeFour.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
clickMeFour.setBackground(Color.gray);
clickMeFour.setForeground(Color.CYAN);
clickMeFour.setName("clickMeFour");
add(clickMeFour);
clickMeFour.setVisible(false);
clickMeFour.addActionListener(new clikMeOneButtonListener());
clickMeFive = new JButton ();
clickMeFive.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
clickMeFive.setBackground(Color.gray);
clickMeFive.setForeground(Color.CYAN);
clickMeFive.setName("clickMeFive");
add(clickMeFive);
clickMeFive.setVisible(false);
clickMeFive.addActionListener(new clikMeOneButtonListener());
clickMeSix = new JButton ();
clickMeSix.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
clickMeSix.setBackground(Color.gray);
clickMeSix.setForeground(Color.CYAN);
clickMeSix.setName("clickMeSix");
add(clickMeSix);
clickMeSix.setVisible(false);
clickMeSix.addActionListener(new clikMeOneButtonListener());
clickMeSeven = new JButton ();
clickMeSeven.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
clickMeSeven.setBackground(Color.gray);
clickMeSeven.setForeground(Color.CYAN);
clickMeSeven.setName("clickMeSeven");
add(clickMeSeven);
clickMeSeven.setVisible(false);
clickMeSeven.addActionListener(new clikMeOneButtonListener());
clickMeOne.setIcon(new ImageIcon("kdevelop_down.png"));
clickMeTwo.setIcon(new ImageIcon("kdevelop_down.png"));
clickMeThree.setIcon(new ImageIcon("kdevelop_down.png"));
clickMeFour.setIcon(new ImageIcon("kdevelop_down.png"));
clickMeFive.setIcon(new ImageIcon("kdevelop_down.png"));
clickMeSix.setIcon(new ImageIcon("kdevelop_down.png"));
clickMeSeven.setIcon(new ImageIcon("kdevelop_down.png"));
clickMeOne.setBorder(new LineBorder(Color.black));
clickMeTwo.setBorder(new LineBorder(Color.black));
clickMeThree.setBorder(new LineBorder(Color.black));
clickMeFour.setBorder(new LineBorder(Color.black));
clickMeFive.setBorder(new LineBorder(Color.black));
clickMeSix.setBorder(new LineBorder(Color.black));
clickMeSeven.setBorder(new LineBorder(Color.black));
validate();
}
private class onePlayerButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == onePlayer) {
lblWelcome.setVisible(false);
playButton.setVisible(false);
helpButton.setVisible(false);
quitButton.setVisible(false);
twoPlayer.setVisible(false);
onePlayer.setVisible(true);
goBack.setVisible(false);
Thread thread =new Thread() {
public void run() {
onePlayer.setText(" Game Starts In ");
onePlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 40));
onePlayer.setBackground(Color.black);
onePlayer.setForeground(Color.BLUE);
try {
Thread.sleep(1000);
}catch (Exception e) {
}
onePlayer.setText("3");
try {
Thread.sleep(1000);
}catch (Exception e) {
}
onePlayer.setText("2");
try {
Thread.sleep(1000);
}catch (Exception e) {
}
onePlayer.setText("1");
try {
Thread.sleep(1000);
}catch (Exception e) {
}
setLayout(new GridLayout(xsize, ysize));
slots = new JButton[xsize - 1][ysize];
for (int column = 0; column < ysize; column++) {
for (int row = 0; row < xsize - 1; row++) {
slots[row][column] = new JButton();
slots[row][column].setHorizontalAlignment(SwingConstants.CENTER);
slots[row][column].setBackground(Color.GREEN);
slots[row][column].setBorder(new LineBorder(Color.black));
add(slots[row][column]);
}
}
lblWelcome.setVisible(false);
remove(lblWelcome);
playButton.setVisible(false);
remove(playButton);
helpButton.setVisible(false);
remove(helpButton);
quitButton.setVisible(false);
remove(quitButton);
goBack.setVisible(false);
remove(goBack);
onePlayer.setVisible(false);
remove(onePlayer);
twoPlayer.setVisible(false);
remove(twoPlayer);
clickMeOne.setVisible(true);
clickMeTwo.setVisible(true);
clickMeThree.setVisible(true);
clickMeFour.setVisible(true);
clickMeFive.setVisible(true);
clickMeSix.setVisible(true);
clickMeSeven.setVisible(true);
}
};
thread.start();
}
}
}
private class twoPlayerButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == twoPlayer) {
lblWelcome.setVisible(false);
playButton.setVisible(false);
helpButton.setVisible(false);
quitButton.setVisible(false);
twoPlayer.setVisible(true);
onePlayer.setVisible(false);
goBack.setVisible(false);
Thread thread =new Thread() {
public void run() {
twoPlayer.setText(" Game Starts In ");
twoPlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 40));
twoPlayer.setBackground(Color.black);
twoPlayer.setForeground(Color.blue);
try {
Thread.sleep(1000);
}catch (Exception e) {
}
twoPlayer.setText("3");
try {
Thread.sleep(1000);
}catch (Exception e) {
}
twoPlayer.setText("2");
try {
Thread.sleep(1000);
}catch (Exception e) {
}
twoPlayer.setText("1");
try {
Thread.sleep(1000);
}catch (Exception e) {
}
setLayout(new GridLayout(xsize, ysize));
slots = new JButton[xsize - 1][ysize];
for (int column = 0; column < ysize; column++) {
for (int row = 0; row < xsize - 1; row++) {
slots[row][column] = new JButton();
slots[row][column].setHorizontalAlignment(SwingConstants.CENTER);
slots[row][column].setBackground(Color.GREEN);
slots[row][column].setBorder(new LineBorder(Color.black));
add(slots[row][column]);
}
}
lblWelcome.setVisible(false);
remove(lblWelcome);
playButton.setVisible(false);
remove(playButton);
helpButton.setVisible(false);
remove(helpButton);
quitButton.setVisible(false);
remove(quitButton);
goBack.setVisible(false);
remove(goBack);
onePlayer.setVisible(false);
remove(onePlayer);
twoPlayer.setVisible(false);
remove(twoPlayer);
clickMeOne.setVisible(true);
clickMeTwo.setVisible(true);
clickMeThree.setVisible(true);
clickMeFour.setVisible(true);
clickMeFive.setVisible(true);
clickMeSix.setVisible(true);
clickMeSeven.setVisible(true);
}
};
thread.start();
}
}
}
private class playButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == playButton) {
lblWelcome.setVisible(true);
playButton.setVisible(false);
helpButton.setVisible(false);
quitButton.setVisible(false);
onePlayer.setVisible(true);
twoPlayer.setVisible(true);
goBack.setVisible(true);
}
}
}
private class goBackButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == goBack) {
lblWelcome.setVisible(true);
playButton.setVisible(true);
helpButton.setVisible(true);
quitButton.setVisible(true);
onePlayer.setVisible(false);
twoPlayer.setVisible(false);
goBack.setVisible(false);
}
}
}
private class CloseListener implements ActionListener{
public void actionPerformed(ActionEvent event) {
if (event.getSource() == quitButton) {
int quitTheGame = JOptionPane.showConfirmDialog(null, " Are You Sure You Want to Leave The Game? ", " Quit? "
, JOptionPane.YES_NO_OPTION);
if (quitTheGame == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
}
}
private class helpListener implements ActionListener{
public void actionPerformed(ActionEvent event) {
if (event.getSource() == helpButton) {
JOptionPane.showMessageDialog(null, " 1) Choose who plays first.", " Help ", JOptionPane.INFORMATION_MESSAGE);
}
}
}
private Color playerColor = Color.red;
private class clikMeOneButtonListener implements ActionListener{
public void actionPerformed(ActionEvent event) {
if (event.getSource() == clickMeOne
|| event.getSource() == clickMeTwo
|| event.getSource() == clickMeThree
|| event.getSource() == clickMeFour
|| event.getSource() == clickMeFive
|| event.getSource() == clickMeSix
|| event.getSource() == clickMeSeven
) {
JButton b = (JButton)event.getSource();
int column = 0;
switch ( b.getName() ) {
case "clickMeOne" : column = 0; break;
case "clickMeTwo" : column = 1; break;
case "clickMeThree" : column = 2; break;
case "clickMeFour" : column = 3; break;
case "clickMeFive" : column = 4; break;
case "clickMeSix" : column = 5; break;
case "clickMeSeven" : column = 6; break;
}
int lastEmptyIdx = -1;
for ( int i = 0; i < slots[column].length; i++ ) {
if ( slots[column][i].getBackground() != Color.green ) {
break;
}
else {
lastEmptyIdx = i;
}
}
if ( lastEmptyIdx != -1 ) {
slots[column][lastEmptyIdx].setBackground(playerColor);
if ( IsWin(column, lastEmptyIdx) ) {
String message = playerColor == Color.red ? " Player One Won!" : " Player Two Won!";
JOptionPane.showMessageDialog(null, message, " Results ", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
} else {
playerColor = playerColor == Color.red ? Color.yellow : Color.red;
}
}
}
}
public boolean IsWin(int column, int row) {
boolean result = false;
// horizontal
boolean found = false;
int counter = 0;
for ( int i = 0; i < slots.length; i++ ) {
if ( slots[i][row].getBackground().equals(playerColor)) {
counter++;
if ( found == true ) {
if ( counter == 4 ) { // win \o/
result = true;
break;
}
}
else {
found = true;
}
}
else {
if ( found == true ) { // reset counter
counter = 0;
}
found = false;
}
}
// vertical
for ( int i = 0; i < slots.length; i++ ) {
if ( slots[column][i].getBackground().equals(playerColor)) {
counter++;
if ( found == true ) {
if ( counter == 4 ) { // win \o/
result = true;
break;
}
}
else {
found = true;
}
}
else {
if ( found == true ) { // reset counter
counter = 0;
}
found = false;
}
}
// diagonal
// TODO
return result;
}
}
}
UPDATE:
for ( int i = 0; i < slots.length; i++ ) {
if ( slots[column][i].getBackground().equals(playerColor)) {
counter++;
column ++;
if (column >= slots.length - 1){
found = false;
break;
}
if ( found == true ) {
if ( counter == 4 ) { // win \o/
result = true;
break;
}
}
else {
found = true;
}
}
else {
if ( found == true ) { // reset counter
counter = 0;
}
found = false;
}
}

Your check needs to not only increment one direction of the slot pane (i), but also needs to increment or decrement what is column in this supposed-to-check-diagonal code to really check along a diagonal.
You also may know there can not be a diagonal win towards a direction if there are less than 4 columns to that side.
**EDIT*: You really should read about language concepts and especially try to understand the concept beyond the syntax! For understanding what is going on, a debugger is an essential tool. If you have a specific algorithm (e.g. your IsWin() method that you need to get insight into, use paper and pencil and do a "manual" execution. This will give you more hints on what might be wrong than any answer to a question with SO. Nevertheless, the references to duplicates of your problem perfectly show what a solution could look like. It is up to you to understand and transfer that to your specific code environment.
To help you a bit further, find below a version of your IsWin() that is working with your code logic. You just need to provide the current playerColor as another parameter. It then will indicate whether the last move lead to a win. (As there can not have been a win before, otherwise it would have been indicated before!). Thus, you just need to check the last move completed a sequence of four in any direction. The code is not truely optimized. There still is room for shortening. But maybe you should first start understanding what you are doing and remove unnecessary garbage from your code....
Suggested code:
public boolean IsWin(final int column, final int row, final Color playerColor) {
boolean won = true;
// vertical
if (row < slots[column].length - 3) {
for (int i = 0; i < 4; i++ ) {
if ( !slots[column][row + i].getBackground().equals(playerColor)) {
won = false;
break;
}
}
if (won) {
return won;
}
}
// to the left
if (column >= 3) {
// horizontal
won = true;
for (int i = 0; i < 4; i++ ) {
if ( !slots[column - i][row].getBackground().equals(playerColor)) {
won = false;
break;
}
}
if (won) {
return won;
}
// diagonal
if (row < slots[column].length - 3) {
won = true;
for (int i = 0; i < 4; i++ ) {
if ( !slots[column - i][row + i].getBackground().equals(playerColor)) {
won = false;
break;
}
}
if (won) {
return won;
}
}
}
// to the right
if (slots.length - column > 3) {
// horizontal
won = true;
for (int i = 0; i < 4; i++ ) {
if ( !slots[column + i][row].getBackground().equals(playerColor)) {
won = false;
break;
}
}
if (won) {
return won;
}
// diagonal
if (row < slots[column].length - 3) {
won = true;
for (int i = 0; i < 4; i++ ) {
if ( !slots[column + i][row + i].getBackground().equals(playerColor)) {
won = false;
break;
}
}
if (won) {
return won;
}
}
}
return false;
}

Related

JPanel is SOMETIMES not responding to mouse clicks

I have some custom JPanels that are used as buttons. This works well 90% of the time, however, sometimes the GUI doesn't respond to a mouse click - the mouseClicked event is not triggered and you have to click again (sometimes even more than once) to actually trigger it.
This behavior appears to be random, though I have the feeling that it occurs more frequently after having moved the frame to another monitor.
Here is the code:
public class EatingMouse extends JFrame implements MouseListener {
JPanel contentPane;
int contentPanelWidth, contentPanelHeight;
int mainTabMarginHeight, mainTabMarginWidth;
int subTabMarginHeight, subTabMarginWidth;
Color fontColor = Color.WHITE;
Color tabBackgroundColor = Color.BLACK;
Color tabBackgroundHighlightColor = Color.GRAY;
Color tabBackgroundSelectedColor = Color.LIGHT_GRAY;
TabPanel firstMainTab;
TabPanel secondMainTab;
ArrayList<TabPanel> firstSubTabs;
ArrayList<TabPanel> secondSubTabs;
ArrayList<TabPanel> currentSubTabs;
int clickCounter;
public EatingMouse() {
super("Why do you eat mouse clicks?");
JLayeredPane layeredPane = new JLayeredPane();
firstMainTab = new TabPanel("First Tab", 18);
firstMainTab.addMouseListener(this);
layeredPane.add(firstMainTab, new Integer(100));
secondMainTab = new TabPanel("Second Tab", 18);
secondMainTab.addMouseListener(this);
layeredPane.add(secondMainTab, new Integer(100));
firstSubTabs = new ArrayList<>();
secondSubTabs = new ArrayList<>();
currentSubTabs = new ArrayList<>();
TabPanel tp = new TabPanel("First First Subtab", 14);
tp.addMouseListener(this);
layeredPane.add(tp, new Integer(100));
firstSubTabs.add(tp);
tp = new TabPanel("Second First Subtab", 14);
tp.addMouseListener(this);
layeredPane.add(tp, new Integer(100));
firstSubTabs.add(tp);
tp = new TabPanel("First Second Subtab", 14);
tp.addMouseListener(this);
layeredPane.add(tp, new Integer(100));
secondSubTabs.add(tp);
tp = new TabPanel("Second Second Subtab", 14);
tp.addMouseListener(this);
layeredPane.add(tp, new Integer(100));
secondSubTabs.add(tp);
contentPane = new JPanel(new BorderLayout());
setContentPane(contentPane);
contentPane.add(layeredPane);
mainTabMarginWidth = 40;
mainTabMarginHeight = 8;
subTabMarginWidth = 20;
subTabMarginHeight = 10;
selectTabs(0, 1);
clickCounter = 0;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(800, 600));
setVisible(true);
}
public void selectTabs(int mainTab, int subTab) {
boolean hasChanged = false;
if((mainTab == 0) && !firstMainTab.isSelected) {
hasChanged = true;
firstMainTab.setSelected(true);
secondMainTab.setSelected(false);
for(TabPanel tp : currentSubTabs) {
tp.setSelected(false);
tp.setVisible(false);
}
currentSubTabs = firstSubTabs;
for(TabPanel tp : currentSubTabs) {
tp.setVisible(true);
}
currentSubTabs.get(subTab).setSelected(true);
}
else if((mainTab == 1) && !secondMainTab.isSelected) {
hasChanged = true;
firstMainTab.setSelected(false);
secondMainTab.setSelected(true);
for(TabPanel tp : currentSubTabs) {
tp.setSelected(false);
tp.setVisible(false);
}
currentSubTabs = secondSubTabs;
for(TabPanel tp : currentSubTabs) {
tp.setVisible(true);
}
currentSubTabs.get(subTab).setSelected(true);
}
else if((mainTab == 0) && firstMainTab.isSelected) {
hasChanged = true;
for(TabPanel tp : currentSubTabs) {
if(tp != currentSubTabs.get(subTab)) { tp.setSelected(false); }
else { tp.setSelected(true); }
}
}
else if((mainTab == 1) && secondMainTab.isSelected) {
hasChanged = true;
for(TabPanel tp : currentSubTabs) {
if(tp != currentSubTabs.get(subTab)) { tp.setSelected(false); }
else { tp.setSelected(true); }
}
}
if(hasChanged) {
revalidate();
repaint();
}
}
#Override
public void paint(Graphics graphics) {
super.paint(graphics);
contentPanelWidth = getContentPane().getWidth();
contentPanelHeight = getContentPane().getHeight();
int xOffset = 100;
int yOffset = 100;
FontMetrics mainTabMetrics = graphics.getFontMetrics(firstMainTab.label.getFont());
firstMainTab.setBounds(xOffset, yOffset, (mainTabMetrics.stringWidth(firstMainTab.text) + mainTabMarginWidth), (mainTabMetrics.getHeight() + mainTabMarginHeight));
xOffset += firstMainTab.getBounds().width;
secondMainTab.setBounds(xOffset, yOffset, (mainTabMetrics.stringWidth(secondMainTab.text) + mainTabMarginWidth), (mainTabMetrics.getHeight() + mainTabMarginHeight));
FontMetrics subTabMetrics = graphics.getFontMetrics(currentSubTabs.get(0).label.getFont());
xOffset = 100;
yOffset += firstMainTab.getBounds().height;
for(TabPanel tp : currentSubTabs) {
tp.setBounds(xOffset, yOffset, (subTabMetrics.stringWidth(tp.text) + subTabMarginWidth), (subTabMetrics.getHeight() + subTabMarginHeight));
tp.revalidate();
tp.repaint();
xOffset += tp.getBounds().width;
}
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("click " + clickCounter++);
Object source = e.getSource();
if(source == firstMainTab && !firstMainTab.isSelected) {
secondMainTab.setSelected(false);
if(currentSubTabs.get(1).isSelected) { selectTabs(0, 1); }
else { selectTabs(0, 0); }
}
else if(source == secondMainTab && !secondMainTab.isSelected) {
if(currentSubTabs.get(1).isSelected) { selectTabs(1, 1); }
else { selectTabs(1, 0); }
}
}
#Override
public void mouseEntered(MouseEvent e) {
Object source = e.getSource();
if(source == firstMainTab && !firstMainTab.isSelected) { firstMainTab.setBackground(tabBackgroundHighlightColor); }
else if(source == secondMainTab && !secondMainTab.isSelected) { secondMainTab.setBackground(tabBackgroundHighlightColor); }
else if(currentSubTabs.contains(source) && !((TabPanel) source).isSelected) {
((TabPanel)source).setBackground(tabBackgroundHighlightColor);
}
}
#Override
public void mouseExited(MouseEvent e) {
Object source = e.getSource();
if(source == firstMainTab && !firstMainTab.isSelected) { firstMainTab.setBackground(tabBackgroundColor); }
else if(source == secondMainTab && !secondMainTab.isSelected) { secondMainTab.setBackground(tabBackgroundColor); }
else if(currentSubTabs.contains(source) && !((TabPanel) source).isSelected) {
((TabPanel)source).setBackground(tabBackgroundColor);
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
public class TabPanel extends JPanel {
JLabel label;
String text;
boolean isSelected;
public TabPanel(String labelText, int fontSize) {
super();
text = labelText;
isSelected = false;
setLayout(new GridBagLayout());
setBackground(tabBackgroundColor);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 0.1;
gbc.weightx = 0.1;
gbc.insets = new Insets(0,0,0,0);
label = new JLabel("<html><div style=\"text-align:center\"> " + text + "</div></html>", SwingConstants.CENTER);
label.setAlignmentX(JLabel.CENTER_ALIGNMENT);
label.setForeground(fontColor);
label.setFont(new Font("Arial", Font.BOLD, fontSize));
add(label, gbc);
}
public void setSelected(boolean selected) {
isSelected = selected;
if(selected) { setBackground(tabBackgroundSelectedColor); }
else { setBackground(tabBackgroundColor); }
}
public boolean isSelected() { return isSelected; }
#Override
public String toString() {
return text + " - " + label.getFont().getSize();
}
}
public static void main(String[] args) {
new EatingMouse();
}
}
Please note that I have chosen JPanels as buttons because I want to heavily customize them later, which I didn't get to work with extending JButton.
Thank you for your time reading this and of course I would appreciate any leads on why this is happening and what I can do to improve this code.

How can I fix my logic error for score deduction and the strike through?

I have been working on the finishing touches for my boggle game for the past couple of days and I have most of the functionality working. Unfortunately there are a few areas that are not working correctly despite the code for said functions being present. No matter how many times I play the game the program fails to notify the user how many words that the computer has found, strike through the randomly selected words, and decrement the player's score based on the matching words.
Boogle UI code:
package userInterface;
/**
*
* #author Zac
*/
import core.Board;
import core.Die;
import java.util.Random;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
public final class BoggleUi {
private Board board;
private JFrame jframe;
//MenuBar
private JMenuBar menubar;
private JMenu boggle;
private JMenuItem game;
private JMenuItem exit;
//Boggle Panel
private Board boggleBoard;
private JPanel bogglePanel;
private ArrayList dictionaryData;//arraylist for dictionary
private ArrayList diceButtons;//arratlist for dicebuttons
ArrayList <String> wordsFoundbyPlayer = new ArrayList();
ArrayList <String> computersWords = new ArrayList();
private JButton[][] dieButton;
//Words Panel
private JPanel wordsPanel;
private JTextArea textArea;
private JScrollPane scrollPane;
private JLabel timerLabel;
private JButton Shakedice;
//InputPanel
private JPanel inputPanel;
private JLabel currentWord;
private JButton submitWord;
private JLabel currentScore;
int score = 0;
//Timer
private int seconds = 59;
private int minutes = 2;
Timer timeCounter;
//Current Word
String currentLetter = "";
String Letters = "";
int rows;
int cols;
private boolean[][] diceButtonCheck;
//style variables
JTextPane wordsArea;
BoggleStyleDoc document;
ArrayList <String> computerWords = new ArrayList();
boolean Randomwords[];
public BoggleUi(Board inBoard, ArrayList readDictionary)
{
diceButtons = new ArrayList();
board = inBoard;
System.out.println(readDictionary.size());
dictionaryData = readDictionary;
initComponents();
}
public void initComponents() {
jframe = new JFrame("Boggle");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setSize(600, 500);
jframe.setMinimumSize(new Dimension(600 , 500));
menubar = new JMenuBar();
document = new BoggleStyleDoc();
//Menu
createMenu();
//Panels
BogglePanel();
WordPanel();
InputPanel();
//Adds Panels to Layout Manager(BorderLayout)
jframe.setJMenuBar( menubar);
jframe.add(bogglePanel, BorderLayout.WEST);
jframe.add(wordsPanel, BorderLayout.CENTER);
jframe.add(inputPanel, BorderLayout.SOUTH);
jframe.setVisible(true);
timeCounter= new Timer(1000, new TimeListener());
}
//Menu Bar
private void createMenu(){
menubar = new JMenuBar();
boggle = new JMenu("Boggle");
game = new JMenuItem("New Game");
game.addActionListener(new GameListener());
exit = new JMenuItem("Exit");
exit.addActionListener(new ExitListener());
boggle.add(game);
boggle.add(exit);
menubar.add(boggle);
}
//Boggle Panel
private void BogglePanel(){
bogglePanel = new JPanel(new GridLayout(4, 4));
bogglePanel.setMinimumSize(new Dimension(400, 400));
bogglePanel.setPreferredSize(new Dimension(400, 400));
bogglePanel.setBorder(BorderFactory.createTitledBorder("Boggle Board"));
ArrayList<Die> dice = board.shakeDice();//array list for dice
dieButton = new JButton[4][4];
diceButtonCheck= new boolean[4][4];
//dieButton.setFont(new Font("Arial", Font.PLAIN, 48));
for(int i=0; i<4; i++){//nested loop for 2d array
for(int j=0; j<4; j++){
String dieLetter = dice.get(4*i +j).getLetter();
dieButton[i][j] = new JButton(dieLetter);
dieButton[i][j].setFont(new Font("Arial", Font.PLAIN, 40));
bogglePanel.add(dieButton[i][j]);
dieButton[i][j].addActionListener(new DiceListener());
dieButton[i][j].setEnabled(false);
diceButtonCheck[i][j] = false;
}
}
}
//Word Panel
private void WordPanel(){
wordsPanel = new JPanel();
wordsPanel.setLayout(new BoxLayout(wordsPanel, BoxLayout.Y_AXIS));
wordsPanel.setBorder(BorderFactory.createTitledBorder("Enter Words Found"));
JPanel noWrapPanel = new JPanel();//new Jpanel for no wrap panel
wordsArea = new JTextPane();
//noWrapPanel.add(wordsArea);//adds the wordsarea to the no wrap panel
wordsArea.setEnabled(false);
scrollPane = new JScrollPane(wordsArea);
scrollPane.add(noWrapPanel);//adds no wrap panel to scroll pane
scrollPane.setPreferredSize(new Dimension(180, 330));
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
timerLabel = new JLabel("3:00");
timerLabel.setHorizontalAlignment(SwingConstants.CENTER);
timerLabel.setFont(new Font("Arial", Font.PLAIN, 45));
timerLabel.setPreferredSize(new Dimension(175, 75));
timerLabel.setMinimumSize(new Dimension(175, 75));
timerLabel.setMaximumSize(new Dimension(175, 75));
timerLabel.setBorder(BorderFactory.createTitledBorder("Time Left"));
Shakedice = new JButton("Shake Dice");
Shakedice.setPreferredSize(new Dimension(175, 50));
Shakedice.setMinimumSize(new Dimension(175, 50));
Shakedice.setMaximumSize(new Dimension(175, 50));
Shakedice.addActionListener(new ShakeListener());
Shakedice.setFont(new Font("Arial", Font.PLAIN, 20));
Shakedice.setEnabled(true);
wordsPanel.add(scrollPane);
wordsPanel.add(timerLabel);
wordsPanel.add(Shakedice);
}
//Input Panel
private void InputPanel(){
//setup input panel
inputPanel = new JPanel();
inputPanel.setLayout(new FlowLayout());
inputPanel.setBorder(BorderFactory.createTitledBorder("Current Word"));
currentWord = new JLabel();
currentWord.setPreferredSize(new Dimension(240, 50));
currentWord.setMinimumSize(new Dimension(240, 50));
currentWord.setMaximumSize(new Dimension(240, 50));
currentWord.setBorder(BorderFactory.createTitledBorder("Current Word"));
//set up submit word button
submitWord = new JButton("Submit Word");
submitWord.setPreferredSize(new Dimension(175, 50));
submitWord.setMinimumSize(new Dimension(175, 50));
submitWord.setMaximumSize(new Dimension(175, 50));
submitWord.addActionListener(new WordListener());
submitWord.setFont(new Font("Arial", Font.PLAIN, 20));
submitWord.setEnabled(false);
//setup score
currentScore = new JLabel();
currentScore.setPreferredSize(new Dimension(100, 50));
currentScore.setMinimumSize(new Dimension(100, 50));
currentScore.setMaximumSize(new Dimension(100, 50));
currentScore.setBorder(BorderFactory.createTitledBorder("Score"));
//adds current word, submit word and current score to the input panel
inputPanel.add(currentWord);
inputPanel.add(submitWord);
inputPanel.add(currentScore);
}
//Exit's the program
private class ExitListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
int response = JOptionPane.showConfirmDialog(null, "Confirm to exit Boggle?",
"Exit?", JOptionPane.YES_NO_OPTION);
if (response == JOptionPane.YES_OPTION)
System.exit(0);
}
}
//New Game( resets JTextArea, time to 3:00 on JLabel, and reenables shake dice button)
private class GameListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
wordsArea.setText("");
Shakedice.setEnabled(true);
submitWord.setEnabled(false);
wordsFoundbyPlayer.clear();
timerLabel.setText("3:00");
minutes=2;
seconds = 59;
timeCounter.stop();
//nested loop to disable the die button
for(int i = 0; i<4; i++ ){
for(int j = 0; j<4; j++){
dieButton[i][j].setEnabled(false);
diceButtonCheck[i][j] = false;
}
}
}
}
//Shakes Dice( shakes dice, starts the timer,
private class ShakeListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
ArrayList<Die> dice = board.shakeDice();
bogglePanel.removeAll();
bogglePanel.revalidate();
Shakedice.setEnabled(false);
submitWord.setEnabled(true);
timeCounter.start();
score = 0;
currentScore.setText(""+ score);
currentLetter = "";
currentWord.setText(currentLetter);
Collections.shuffle(dice);
dieButton = new JButton[4][4];
diceButtonCheck= new boolean[4][4];
for(int i=0; i<4; i++){
for(int j=0; j<4; j++){
String dieLetter = dice.get(4*i +j).getLetter();
dieButton[i][j] = new JButton(dieLetter);
dieButton[i][j].setFont(new Font("Arial", Font.PLAIN, 40));
bogglePanel.add(dieButton[i][j]);
dieButton[i][j].addActionListener(new DiceListener());
dieButton[i][j].setEnabled(true);
diceButtonCheck[i][j] = false;
}
}
}
}
//word listener
private class WordListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
int flag = 0; //flag varible
boolean validateWord = false;// variable to validate a word
for(int n = 0; n < wordsFoundbyPlayer.size(); n++){
if(wordsFoundbyPlayer.get(n).compareTo(currentLetter) == 0){
validateWord = true;
}
}
wordsArea.setDocument(document);
if(validateWord == false){
wordsFoundbyPlayer.add(currentLetter);
for(int i=0; i< dictionaryData.size(); i++){
if(currentLetter.equalsIgnoreCase(dictionaryData.get(i).toString())){
flag = 1;
int wordLength = currentLetter.length();
if(wordLength <= 2){
try {
document.insertString(0,"Word is too short!\n",null);
//internal try catch block
} catch (BadLocationException ex) {
Logger.getLogger(BoggleUi.class.getName()).log(Level.SEVERE, null, ex);
}
}
else if(wordLength <= 4){
try {
score += 1;
document.insertString(0,currentLetter+"\n",null);
} catch (BadLocationException ex) {
Logger.getLogger(BoggleUi.class.getName()).log(Level.SEVERE, null, ex);
}
}
else if(wordLength == 5){
try {
score += 2;
document.insertString(0,currentLetter+"\n",null);
} catch (BadLocationException ex) {
Logger.getLogger(BoggleUi.class.getName()).log(Level.SEVERE, null, ex);
}
}
else if(wordLength == 6){
try {
score += 3;
document.insertString(0,currentLetter+"\n",null);
} catch (BadLocationException ex) {
Logger.getLogger(BoggleUi.class.getName()).log(Level.SEVERE, null, ex);
}
}
else if(wordLength == 7){
try {
score += 5;
document.insertString(0,currentLetter+"\n",null);
} catch (BadLocationException ex) {
Logger.getLogger(BoggleUi.class.getName()).log(Level.SEVERE, null, ex);
}
}
else if(wordLength >= 8){
try {
score += 11;
document.insertString(0,currentLetter+"\n",null);
} catch (BadLocationException ex) {
Logger.getLogger(BoggleUi.class.getName()).log(Level.SEVERE, null, ex);
}
}
break;
}
}
//check if the word entered is vaild or not
if(flag == 0){
//surrounding try catch statement
try {
document.insertString(0,"Word is invalid!\n", null);
} catch (BadLocationException ex) {
Logger.getLogger(BoggleUi.class.getName()).log(Level.SEVERE, null, ex);
}
}
//for loop to caluate score based on length
for(int i = 0; i<4; i++ ){
for(int j = 0; j<4; j++){
dieButton[i][j].setEnabled(true);
diceButtonCheck[i][j] = false;
}
}
}
if(validateWord == true){
JOptionPane.showMessageDialog(null, "Word is a repeat!");
}
currentLetter = "";
currentWord.setText(currentLetter);
currentScore.setText(""+score);
}
}
//dice listener
private class DiceListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
JButton b;
Letters = e.getActionCommand();
b = (JButton)e.getSource();
currentLetter += Letters;
currentWord.setText(currentLetter);
for(int i = 0; i<4; i++ ){//nested loop for validation
for(int j = 0; j<4; j++){
dieButton[i][j].setEnabled(false);
if(b == dieButton[i][j]){
rows = i;
cols = j;
diceButtonCheck[i][j] = true;
}
}
}
for(int i = rows -1; i <= rows +1; i++ ){//nested loop to enable or disable the die button
for(int j = cols -1; j <= cols +1; j++ ){
if( i>=0 && i<4 && j>=0 && j<4) {
dieButton[i][j].setEnabled(true);
if(diceButtonCheck[i][j])
dieButton[i][j].setEnabled(false);
}
}
}
}
}
//Actionlistener for the timer
private class TimeListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
String s = String.format(" "+minutes+ ":" + "%02d", seconds);//concatenate minutes and seconds
timerLabel.setText(s);
seconds -=1;
if(seconds < 0){
seconds=59;
if(minutes == 0){
timeCounter.stop();
submitWord.setEnabled(false);//sets button to false
JOptionPane.showMessageDialog(null, "Game Over");//option pane for game over
JOptionPane.showMessageDialog(null, "The Computer will now compare its words to yours");
for(int i = 0; i<4; i++ ){
for(int j = 0; j<4; j++){
dieButton[i][j].setEnabled(false);
diceButtonCheck[i][j] = false;
}
}
return;
}
minutes--;
}
}
}
//method for random word selection
private void randomWordselect(){
Random randomWord = new Random();
int randWord = randomWord.nextInt(wordsFoundbyPlayer.size());
if(Randomwords[randWord] != true){
Randomwords[randWord] = true;
}
else{
randomWordselect();
}
}
//method for comparing the computer's words against the player's
private void ComputerCompare(){
Random rand = new Random();
int numAIWords = rand.nextInt(wordsFoundbyPlayer.size());
Randomwords = new boolean[wordsFoundbyPlayer.size()];
for(int j = 0; j < numAIWords; j++){
randomWordselect();
}
//for loop to set up strike through
for(int i = 0; i < wordsFoundbyPlayer.size(); i++ ){
StyleConstants.setStrikeThrough(document.getterStyle(), true);
wordsArea.setDocument(document);
}
//for loop with the switch case statement to decrement the player's score
for(int n = 0; n < wordsFoundbyPlayer.size(); n++){
if(Randomwords[n] == true){
System.out.println( "Word" + n + "of the Player's words were found");
StyleConstants.setStrikeThrough(document.getterStyle(), true);
wordsArea.setDocument(document);
int deduction = wordsFoundbyPlayer.get(n).length();
switch(deduction){
case 0:
case 1:
case 2:
score -=0;
break;
case 3:
case 4:
score -= 1;
break;
case 5:
score -= 2;
break;
case 6:
score -= 3;
break;
case 7:
score -= 5;
break;
default:
score -= 11;
break;
}
currentScore.setText(String.valueOf(score));
System.out.println("Your total score is" + score);
}
else{
StyleConstants.setStrikeThrough(document.getterStyle(),false);
wordsArea.setDocument(document);
}
try{//try catch for location
document.insertString(document.getLength(),wordsFoundbyPlayer.get(n) + "\n", null) ;
}
catch(Exception ex){
System.out.println("Bad Location");
}
}
}
// external private class for the default styled document
private class BoggleStyleDoc extends DefaultStyledDocument{
private Style primaryStyle;
public BoggleStyleDoc(){
super();
primaryStyle = this.addStyle("primary", null);
}
public Style getterStyle() {
return primaryStyle;
}
#Override
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException{
super.insertString(offs, str, primaryStyle);
}
}
}
As you can tell everything should look correct, but I'm still having issues. I believe the error is somewhere within one of the implementations of wordsArea, but I can't pinpoint where I would need to make the fix. Can someone show or tell me how I could possibly resolve the issues?

java Swing timer to perform few tasks one after another

I am perfectly aware very similar questions few asked before. I have tried to implement solutions offered - in vain. ...The problem i am facing is to blink buttons ONE AFTER ANOTHER. I can do it for one, but when put the order of blinking in a loop - everything breaks. Any help to a new person to Java is appreciated. P.S. I am not allowed to use Threads. What i am having now is:
Timer colorButton = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < pcArray.length; i++) {
playSquare = pcArray[i];
System.out.println("PlaySquare " + playSquare);
if (playSquare == 1) {
if (alreadyColoredRed) {
colorBack.start();
colorButton.stop();
} else {
red.setBackground(Color.red);
alreadyColoredRed = true;
System.out.println("RED DONE");
}
} else if (playSquare == 2) {
if (alreadyColoredGreen) {
colorBack.start();
colorButton.stop();
} else {
green.setBackground(Color.green);
alreadyColoredGreen = true;
System.out.println("GREEN DONE");
}
}
}
}
});
Timer colorBack = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < pcArray.length; i++) {
playSquare = pcArray[i];
System.out.println("PlaySquare " + playSquare);
if (playSquare == 1) {
red.setBackground(Color.gray);
alreadyColoredRed = false;
System.out.println("RED PAINTED BACK");
colorBack.stop();
} else if (playSquare == 2) {
green.setBackground(Color.gray);
alreadyColoredGreen = false;
System.out.println("GREEN PAINTED BACK");
colorBack.stop();
}
}
}
});
I don't think that having two Timer instances is the way to go. The Swing Timer is notorious for 'drifting' away from the perfect beat over time.
Better to create a single timer with the logic needed to control all actions.
E.G. Showing the allowable moves for a Chess Knight.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class KnightMove {
KnightMove() {
initUI();
}
ActionListener animationListener = new ActionListener() {
int blinkingState = 0;
#Override
public void actionPerformed(ActionEvent e) {
final int i = blinkingState % 4;
chessSquares[7][1].setText("");
chessSquares[5][0].setText("");
chessSquares[5][2].setText("");
switch (i) {
case 0:
setPiece(chessSquares[5][0], WHITE + KNIGHT);
break;
case 1:
case 3:
setPiece(chessSquares[7][1], WHITE + KNIGHT);
break;
case 2:
setPiece(chessSquares[5][2], WHITE + KNIGHT);
}
blinkingState++;
}
};
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new GridLayout(8, 8));
ui.setBorder(new CompoundBorder(new EmptyBorder(4, 4, 4, 4),
new LineBorder(Color.BLACK,2)));
boolean black = false;
for (int r = 0; r < 8; r++) {
for (int c = 0; c < 8; c++) {
JLabel l = getColoredLabel(black);
chessSquares[r][c] = l;
ui.add(l);
black = !black;
}
black = !black;
}
for (int c = 0; c < 8; c++) {
setPiece(chessSquares[0][c], BLACK + STARTING_ROW[c]);
setPiece(chessSquares[1][c], BLACK + PAWN);
setPiece(chessSquares[6][c], WHITE + PAWN);
setPiece(chessSquares[7][c], WHITE + STARTING_ROW[c]);
}
Timer timer = new Timer(750, animationListener);
timer.start();
}
private void setPiece(JLabel l, int piece) {
l.setText("<html><body style='font-size: 60px;'>&#" + piece + ";");
}
private final JLabel getColoredLabel(boolean black) {
JLabel l = new JLabel();
l.setBorder(new LineBorder(Color.DARK_GRAY));
l.setOpaque(true);
if (black) {
l.setBackground(Color.GRAY);
} else {
l.setBackground(Color.WHITE);
}
return l;
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
KnightMove o = new KnightMove();
JFrame f = new JFrame("Knight Moves");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.setResizable(false);
f.pack();
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
private JComponent ui = null;
JLabel[][] chessSquares = new JLabel[8][8];
public static final int WHITE = 9812, BLACK = 9818;
public static final int KING = 0, QUEEN = 1,
ROOK = 2, KNIGHT = 4, BISHOP = 3, PAWN = 5;
public static final int[] STARTING_ROW = {
ROOK, KNIGHT, BISHOP, KING, QUEEN, BISHOP, KNIGHT, ROOK
};
}

Hello I am creating a TicTacToe game for myself to understand Java better

however I am not sure where I am supposed to enter the whoWins() method. Do I enter this method in the actionperformed Method of the buttons or do i need to something different. Please help.
public class TTT extends JFrame implements ActionListener {
private JButton buttons[] = new JButton[9];
private JButton exitButton;
public JLabel title;
public JPanel titlePanel, panel;
private int count = 0;
int symbolCount = 0;
private boolean win = false;
public TTT() {
title = new JLabel("Welcome to my Tic Tac Toe Game!");
titlePanel = new JPanel();
title.setFont(new Font(Font.SERIF, 0, 30));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.NORTH);
panel = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton();
panel.add(buttons[i]);
buttons[i].setEnabled(true);
buttons[i].addActionListener(this);
}
this.add(panel, BorderLayout.CENTER);
JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
exitButton = new JButton("Quit");
panel1.add(exitButton);
this.add(panel1, BorderLayout.SOUTH);
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(WIDTH);
}
});
}
public void whoWins() {
//Determines who wins using for the horizontal rows.
if (buttons[0].getText() == buttons[1].getText() && buttons[1].getText() == buttons[2].getText() && buttons[0].getText() != "") {
win = true;
} else if (buttons[3].getText() == buttons[4].getText() && buttons[4].getText() == buttons[5].getText() && buttons[3].getText() != "") {
win = true;
} else if (buttons[6].getText() == buttons[7].getText() && buttons[7].getText() == buttons[8].getText() && buttons[6].getText() != "") {
win = true;
} //Determines the verticles wins
else if (buttons[0].getText() == buttons[3].getText() && buttons[3].getText() == buttons[6].getText() && buttons[0].getText() != "") {
win = true;
} else if (buttons[1].getText() == buttons[4].getText() && buttons[4].getText() == buttons[7].getText() && buttons[1].getText() != "") {
win = true;
} else if (buttons[2].getText() == buttons[5].getText() && buttons[5].getText() == buttons[8].getText() && buttons[2].getText() != "") {
win = true;
}
// Diagnol Wins
else if (buttons[0].getText()==buttons[4].getText()&&buttons[4].getText()==buttons[8].getText()&& buttons[0].getText()!= "") {
win = true;
}else if (buttons[2].getText()==buttons[4].getText()&&buttons[4].getText()==buttons[6].getText()&& buttons[1].getText()!= "") {
win = true;
}else {
win = false;
}
//who won
if (win = true) {
JOptionPane.showMessageDialog(null, "wins");
}else if (count == 9 && win == false) {
JOptionPane.showMessageDialog(null, "Tie game");
}
}
public static void main(String[] args) {
TTT ref1 = new TTT();
ref1.setTitle("Tic Tac Toe");
ref1.setVisible(true);
ref1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ref1.setSize(500, 500);
ref1.setLocationRelativeTo(null);
// ref1.whoWins();
}
#Override
public void actionPerformed(ActionEvent e) {
count++;
for (JButton button : buttons) {
if (button == e.getSource()) {
if (symbolCount % 2 == 0) {
button.setText("X");
button.setEnabled(false);
} else {
button.setText("O");
button.setEnabled(false);
}
}
}
if (count >= buttons.length) {
JOptionPane.showMessageDialog(null, "End");
}
symbolCount++;
}
}
If you really want to do this right, then I suggest making some big changes, some M-V-C type changes:
First and foremost, separate out the logic of the game from the game GUI. This would mean that the code that determines who wins should not be in any code that contains GUI type code. This will be your "model"
Next you should never have GUI code implement listener interfaces, so try to get that out of the GUI and possibly have it go into its own class, the "Control" class.
Finally the GUI or "View" class will concern itself with displaying the model's state and getting input from the user and transmitting this input to the control.
For example,...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class TicTacToeMain {
private static void createAndShowGui() {
TttView view = null;
try {
view = new TttView();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
TttModel model = new TttModel();
new TttControl(model, view);
JFrame frame = new JFrame("Tic Tac Toe");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(view.getMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum TttPiece {
EMPTY, X, O
}
class TttView {
public static final String IMAGE = "/imgFolder/TicTacToe.png";
private static final int GAP = 5;
private JPanel mainPanel = new JPanel();
private JPanel tttPanel = new JPanel();
private Map<TttPiece, Icon> iconMap = new EnumMap<>(TttPiece.class);
private JLabel[][] grid = new JLabel[TttModel.ROWS][TttModel.COLS];
private TttControl control;
public TttView() throws IOException {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream(IMAGE));
Icon[] imgIcons = splitImg(img);
iconMap.put(TttPiece.X, imgIcons[0]);
iconMap.put(TttPiece.O, imgIcons[1]);
iconMap.put(TttPiece.EMPTY, createEmptyIcon(imgIcons[0]));
tttPanel.setLayout(new GridLayout(grid.length, grid[0].length, GAP, GAP));
tttPanel.setBackground(Color.black);
MyMouseAdapter mouseAdapter = new MyMouseAdapter();
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
grid[row][col] = new JLabel(iconMap.get(TttPiece.EMPTY));
grid[row][col].setOpaque(true);
grid[row][col].setBackground(Color.LIGHT_GRAY);
grid[row][col].addMouseListener(mouseAdapter);
tttPanel.add(grid[row][col]);
}
}
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));
btnPanel.add(new JButton(new ClearAction("Clear", KeyEvent.VK_C)));
btnPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
int blGap = 2;
mainPanel.setLayout(new BorderLayout(blGap, blGap));
mainPanel.setBorder(BorderFactory.createEmptyBorder(blGap, blGap, blGap,
blGap));
mainPanel.add(tttPanel, BorderLayout.CENTER);
mainPanel.add(btnPanel, BorderLayout.SOUTH);
}
public void setControl(TttControl control) {
this.control = control;
}
public JComponent getMainPanel() {
return mainPanel;
}
private Icon createEmptyIcon(Icon icon) {
int width = icon.getIconWidth();
int height = icon.getIconHeight();
BufferedImage img = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
return new ImageIcon(img);
}
private Icon[] splitImg(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
int gap = 5;
Icon[] icons = new ImageIcon[2];
icons[0] = new ImageIcon(img.getSubimage(0, 0, w / 2 - gap, h / 2 - gap));
icons[1] = new ImageIcon(img.getSubimage(w / 2 + gap, 0, w / 2 - gap, h
/ 2 - gap));
return icons;
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if (control == null) {
return;
}
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
if (grid[row][col] == e.getSource()) {
control.gridPress(row, col);
}
}
}
}
}
private class ClearAction extends AbstractAction {
public ClearAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent evt) {
if (control != null) {
control.clear();
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent evt) {
if (control != null) {
control.exit(evt);
}
}
}
public void setGridIcon(int row, int col, TttPiece tttPiece) {
grid[row][col].setIcon(iconMap.get(tttPiece));
}
}
class TttControl {
private TttModel model;
private TttView view;
public TttControl(TttModel model, TttView view) {
this.model = model;
this.view = view;
view.setControl(this);
model.addPropertyChangeListener(new ModelListener());
}
public void exit(ActionEvent evt) {
Window win = SwingUtilities
.getWindowAncestor((Component) evt.getSource());
win.dispose();
}
public void gridPress(int row, int col) {
try {
model.gridPress(row, col);
} catch (TttException e) {
// TODO: notify user
// e.printStackTrace();
}
}
public void clear() {
model.clear();
}
private class ModelListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (TttModel.GRID_POSITION.equals(evt.getPropertyName())) {
TttPiece[][] tttGrid = model.getTttGrid();
for (int row = 0; row < tttGrid.length; row++) {
for (int col = 0; col < tttGrid[row].length; col++) {
view.setGridIcon(row, col, tttGrid[row][col]);
}
}
}
}
}
}
class TttModel {
public static final int ROWS = 3;
public static final int COLS = ROWS;
public static final String GRID_POSITION = "grid position";
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
private TttPiece[][] tttGrid = new TttPiece[ROWS][COLS];
private TttPiece player = TttPiece.X;
private boolean gameOver;
public TttModel() {
clear();
}
public void setGridPosition(int row, int col, TttPiece piece)
throws TttException {
if (gameOver) {
return;
}
if (tttGrid[row][col] == TttPiece.EMPTY) {
tttGrid[row][col] = piece;
checkForWin(row, col, piece);
nextPlayer();
pcSupport.firePropertyChange(GRID_POSITION, null, tttGrid);
} else {
String message = "Invalid setGridPosition for row: %d, col: %d, piece: %s. "
+ "Spot already occupied by piece: %s";
message = String.format(message, row, col, piece, tttGrid[row][col]);
throw new TttException(message);
}
}
public TttPiece[][] getTttGrid() {
return tttGrid;
}
public void gridPress(int row, int col) throws TttException {
setGridPosition(row, col, player);
}
public void nextPlayer() {
player = player == TttPiece.X ? TttPiece.O : TttPiece.X;
}
private void checkForWin(int row, int col, TttPiece piece) {
// TODO finish
}
public void clear() {
for (int row = 0; row < tttGrid.length; row++) {
for (int col = 0; col < tttGrid[row].length; col++) {
tttGrid[row][col] = TttPiece.EMPTY;
}
}
player = TttPiece.X;
pcSupport.firePropertyChange(GRID_POSITION, null, tttGrid);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
#SuppressWarnings("serial")
class TttException extends Exception {
public TttException() {
super();
}
public TttException(String message) {
super(message);
}
}
Using for my images:
With GUI looking like:
I am also interested in writing a Tic Tac Toe game, so I copied your code, and did a little modification, and it passed test, check following:
package eric.j2se.swing;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* <p>
* Simple game of Tic Tac Toe.
* </p>
*
* #author eric
* #date Apr 16, 2014 11:03:48 AM
*/
#SuppressWarnings("serial")
public class TicTacToe extends JFrame implements ActionListener {
// 2 players
public static final char playerX = 'X';
public static final char playerO = 'O';
// null player
public static final char playerN = 'N';
// the winer, init to null player
private Character winner = playerN;
// indicate whether game over
private boolean gameOver = false;
// count of button used,
private int count = 0;
private Character buttonPlayers[] = new Character[9];
private JButton buttons[] = new JButton[9];
private JButton exitButton;
public JLabel title;
public JPanel titlePanel, panel;
public TicTacToe() {
// init buttonPlayers
for (int i = 0; i < 9; i++) {
buttonPlayers[i] = playerN;
}
// init title
title = new JLabel("Welcome to Tic Tac Toe!");
titlePanel = new JPanel();
title.setFont(new Font(Font.SERIF, 0, 30));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.NORTH);
// init 9 button
panel = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton();
panel.add(buttons[i]);
buttons[i].setEnabled(true);
buttons[i].addActionListener(this);
}
// init exit button
this.add(panel, BorderLayout.CENTER);
JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
exitButton = new JButton("Quit");
panel1.add(exitButton);
this.add(panel1, BorderLayout.SOUTH);
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(WIDTH);
}
});
}
public void whoWins() {
// determine winner - horizontal rows
if (!gameOver) {
for (int i = 0; i < 3; i++) {
if ((buttonPlayers[0 + i * 3] != playerN) && (buttonPlayers[0 + i * 3].equals(buttonPlayers[1 + i * 3]))
&& buttonPlayers[1 + i * 3].equals(buttonPlayers[2 + i * 3])) {
winner = buttonPlayers[0 + i * 3];
gameOver = true;
break;
}
}
}
// determine winner - vertical rows
if (!gameOver) {
for (int i = 0; i < 3; i++) {
if ((buttonPlayers[i + 0 * 3] != playerN) && (buttonPlayers[i + 0 * 3].equals(buttonPlayers[i + 1 * 3]))
&& buttonPlayers[i + 1 * 3].equals(buttonPlayers[i + 2 * 3])) {
winner = buttonPlayers[i + 0 * 3];
gameOver = true;
break;
}
}
}
// determine winner - diagonal rows
if (!gameOver) {
int winButtonIndex = -1;
if ((buttonPlayers[0] != playerN) && (buttonPlayers[0].equals(buttonPlayers[4])) && buttonPlayers[4].equals(buttonPlayers[8])) {
winButtonIndex = 0;
} else if ((buttonPlayers[2] != playerN) && (buttonPlayers[2].equals(buttonPlayers[4])) && buttonPlayers[4].equals(buttonPlayers[6])) {
winButtonIndex = 2;
}
if (winButtonIndex >= 0) {
winner = buttonPlayers[winButtonIndex];
gameOver = true;
}
}
// full
if (count == 9) {
gameOver = true;
}
if (gameOver) {
String tip = "";
switch (winner) {
case playerO:
tip = "Player O win!";
break;
case playerX:
tip = "Player X win!";
break;
default:
tip = "Draw game!";
break;
}
JOptionPane.showMessageDialog(null, tip);
}
}
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < buttons.length; i++) {
JButton button = buttons[i];
if (button == e.getSource()) {
Character currentPlayer = (count % 2 == 1 ? playerX : playerO);
button.setText(String.valueOf(currentPlayer));
buttonPlayers[i] = currentPlayer;
button.setEnabled(false);
break;
}
}
count++;
whoWins();
}
public static void main(String[] args) {
TicTacToe ref1 = new TicTacToe();
ref1.setTitle("Tic Tac Toe");
ref1.setVisible(true);
ref1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ref1.setSize(500, 500);
ref1.setLocationRelativeTo(null);
}
}
about when to call the win check:
check each time you click 1 of the 9 buttons,
about the flag:
I use 2 flag instead of 1 flag to indicate game over & winner, because in TTT game, draw game is very usual, after play several times, you always get draw game ...
a little suggestion to your code:
when compare string, use equals(), not ==,
define const values in variable, not write it in logic, e.g. 'O' 'X',
don't repeat code, try use logic control to make it short & easy to read & easy to maintain,

How do I add a scroll bar in a null layout?

I have been trying to get a scroll bar on my JTextArea for days, I've tried every way to do it as I could find. I am making a Chat Client and I have the JPanel setup with a null layout. I've tried using the Layout Managers but I don't understand how to get it to look the way I want.
I just want a scroll bar on the text area. I'm a beginner and for what I've read it isn't possible to have one with a null layout? I'm open to help changing the layout if that's easier also.
package guiserver;
import com.apple.eawt.Application;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
public class GUIserver extends JFrame implements ActionListener {
JFrame login = new JFrame();
JPanel panel = new JPanel();
JPanel main = new JPanel();
JFrame accept = new JFrame();
JPanel acpt = new JPanel();
JPanel buttonpanel = new JPanel();
JButton acceptinvite = new JButton("Accept Invite");
JButton denyinvite = new JButton("Deny Invite");
JLabel acceptlabel = new JLabel();
JLabel acceptname = new JLabel();
JPanel loginpanel = new JPanel();
JTextArea chat = new JTextArea(" Waiting to Start Client...");
JSplitPane chatsplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
JTextField input = new JTextField();
JScrollPane pane = new JScrollPane(chat);
JButton send = new JButton("Send");
JLabel IP = new JLabel("IP:... ");
JButton start = new JButton("Start");
sendThread s1 = new sendThread();
fromThread f1 = new fromThread();
infoFromThread f2 = new infoFromThread();
infoToThread s2 = new infoToThread();
RPSpickTimer pt = new RPSpickTimer();
myCanvas contact = new myCanvas();
myCanvas logo = new myCanvas();
JButton rock = new JButton("Rock");
JButton paper = new JButton("Paper");
JButton scissors = new JButton("Scissors");
JTextField username = new JTextField();
JLabel loguser = new JLabel("Username:");
JLabel logpass = new JLabel("Password:");
JPasswordField password = new JPasswordField();
JButton signin = new JButton("Sign in");
String inputText = "0";
String chatCurrent;
String out1;
String in;
boolean pause = true;
boolean rps = false;
int P1pick = 0;
int P2pick = 0;
String user = "User 1";
String user2 = "Jacob Abthorpe";
String pass;
int badge;
int sendinvite = 0;
char answerinvite = '-';
boolean pauseInfo = true;
int winner = 0;
public GUIserver() {
Application application = Application.getApplication();
Image image = Toolkit.getDefaultToolkit().getImage("src/icon.png");
application.setDockIconImage(image);
login.setVisible(true);
login.setSize(400, 500);
login.setLocationRelativeTo(null);
login.setTitle("Login");
login.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
login.add(loginpanel);
loginpanel.setLayout(null);
loginpanel.add(username);
loginpanel.add(password);
loginpanel.add(signin);
loginpanel.add(logpass);
loginpanel.add(loguser);
loginpanel.add(logo);
login.setAlwaysOnTop(true);
username.setHorizontalAlignment(JTextField.CENTER);
password.setHorizontalAlignment(JTextField.CENTER);
username.setBounds(50, 290, 300, 30);
password.setBounds(50, 350, 300, 30);
loguser.setBounds(55, 265, 300, 30);
logpass.setBounds(55, 325, 300, 30);
signin.setBounds(150, 400, 100, 30);
logo.setBounds(110, 50, 150, 150);
username.addActionListener(this);
password.addActionListener(this);
signin.addActionListener(this);
setVisible(false);
setSize(500, 600);
setLocationRelativeTo(null);
setTitle("Chat Server Client");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setAlwaysOnTop(true);
panel.setLayout(null);
panel.setLocation(300, 0);
panel.add(pane);
panel.add(input);
panel.add(send);
panel.add(IP);
panel.add(start);
panel.add(rock);
panel.add(paper);
panel.add(scissors);
contact.picx = 120;
contact.picy = 120;
contact.setBackground(Color.white);
contact.setBounds(370, 10, 120, 120);
panel.add(contact);
input.addActionListener(this);
send.addActionListener(this);
start.addActionListener(this);
rock.addActionListener(this);
paper.addActionListener(this);
scissors.addActionListener(this);
chat.setEditable(false);
pane.setBounds(10, 10, 350, 450);
input.setEditable(false);
input.setBounds(10, 470, 350, 80);
start.setBounds(370, 470, 115, 80);
IP.setBounds(15, 520, 480, 80);
rock.setVisible(false);
paper.setVisible(false);
scissors.setVisible(false);
scissors.setBounds(370, 430, 115, 30);
paper.setBounds(370, 400, 115, 30);
rock.setBounds(370, 370, 115, 30);
setContentPane(panel);
accept.setVisible(false);
accept.setSize(400, 125);
accept.setLocationRelativeTo(null);
accept.setTitle("Rock, Paper, Scissors");
accept.setAlwaysOnTop(true);
accept.setResizable(false);
accept.add(acpt);
acpt.setLayout(null);
acpt.add(acceptlabel);
acpt.add(buttonpanel);
acpt.add(acceptname);
buttonpanel.setBounds(0, 60, 400, 40);
buttonpanel.setLayout(new FlowLayout());
acceptlabel.setHorizontalAlignment(SwingConstants.CENTER);
acceptlabel.setText("would like to play Rock, Paper, Scissors. Accept?");
acceptlabel.setBounds(0, 25, 400, 40);
acceptname.setHorizontalAlignment(SwingConstants.CENTER);
acceptname.setText(user2 + "");
acceptname.setBounds(0, 3, 400, 40);
buttonpanel.add(acceptinvite);
buttonpanel.add(denyinvite);
acceptinvite.addActionListener(this);
denyinvite.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == input) {
if (input.getText().startsWith("/")) {
if (input.getText().contentEquals("/")) {
chat.append("\n\n >Type '/help' for list of all commands");
}
if (input.getText().contentEquals("/start RPS")) {
chat.append("\n \n >Waiting for opponent to accept invite. . .");
pauseInfo = false;
sendinvite = 10;
}
if (input.getText().contentEquals("/help")) {
chat.append("\n\n >Type '/help' for list of all commands");
chat.append("\n >Type '/start RPS' to play Rock Paper Scissors");
chat.append("\n >Type '/end' to quit current game");
}
if (input.getText().contentEquals("/end")) {
if (rps == true) {
chat.append("\n\n >Quiting Rock, Paper, Scissors. . .");
rps = false;
rock.setVisible(false);
paper.setVisible(false);
scissors.setVisible(false);
}
}
input.setText("");
} else {
if ((input.getText().contentEquals("")) && (input.getText().contentEquals(" "))) {
Toolkit.getDefaultToolkit().beep();
} else {
pause = false;
chat.append("\n \n " + user + " says: \n " + input.getText());
inputText = input.getText();
input.setText("");
}
}
}
if (e.getSource() == send) {
//chat.append("\n \n Dale Schmidt says: \n " + inputText);
//pause = false;
}
if (e.getSource() == username) {
user = username.getText();
}
if (e.getSource() == signin) {
login.setVisible(false);
setVisible(true);
}
if (e.getSource() == start) {
try {
s1.start();
f1.start();
s2.start();
f2.start();
setAlwaysOnTop(false);
chat.append("\n " + InetAddress.getLocalHost() + "\n Server started.");
IP.setText("IP: " + InetAddress.getLocalHost());
start.setVisible(false);
send.setVisible(true);
input.setEditable(true);
send.setBounds(370, 470, 115, 80);
} catch (Exception s) {
System.out.print("YOLOerror starting server");
}
}
if (e.getSource() == rock) {
if ((rps == true) && (P1pick == 0)) {
P1pick = 1;
chat.append("\n\n >You picked 'Rock'");
if (P2pick != 0) {
pt.start();
}
}
}
if (e.getSource() == paper) {
if ((rps == true) && (P1pick == 0)) {
P1pick = 2;
chat.append("\n\n >You picked 'Paper'");
if (P2pick != 0) {
pt.start();
}
}
}
if (e.getSource() == scissors) {
if ((rps == true) && (P1pick == 0)) {
P1pick = 3;
chat.append("\n\n >You picked 'Scissors'");
if (P2pick != 0) {
pt.start();
}
}
}
if (e.getSource() == acceptinvite) {
rps = true;
rock.setVisible(true);
paper.setVisible(true);
scissors.setVisible(true);
answerinvite = 'y';
accept.dispose();
}
if (e.getSource() == denyinvite) {
answerinvite = 'n';
accept.dispose();
}
}
class myCanvas extends Canvas {
int x = 10, y = 10;
int picx = 150, picy = 150;
public void paint(Graphics g) {
Image image1 = Toolkit.getDefaultToolkit().getImage("src/icon.png");
g.drawImage(image1, x, y, picx, picy, this);
}
}
class sendThread extends Thread {
ServerSocket s1;
Socket sendclientSocket = null;
public void run() {
inputText = input.getText();
try {
System.err.println("Starting Send Server");
System.out.println(InetAddress.getLocalHost());
s1 = new ServerSocket(4444);
sendclientSocket = s1.accept();
System.err.println("Started Send Server");
} catch (Exception s1) {
System.exit(1);
}
while (true) {
try {
PrintWriter out = new PrintWriter(sendclientSocket.getOutputStream(), true);
if (pause == false) {
badge = 0;
out.println(input.getText());
System.out.println("sent");
pause = true;
}
} catch (Exception e) {
System.err.println("Error Sending.");
System.err.println(e.getMessage());
System.exit(2);
}
}
}
}
class fromThread extends Thread {
ServerSocket s2;
Socket fromclientSocket = null;
public void run() {
try {
System.err.println("Starting Recieve Server");
s2 = new ServerSocket(4441);
fromclientSocket = s2.accept();
System.err.println("Started Recieve Server");
} catch (Exception s2) {
System.exit(1);
}
while (true) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(fromclientSocket.getInputStream()));
String fromClient = in.readLine();
if (fromClient.contentEquals("")) {
} else {
Toolkit.getDefaultToolkit().beep();
chat.append("\n\n " + user2 + " says:\n " + fromClient);
badge++;
Application.getApplication().setDockIconBadge(Integer.toString(badge));
}
} catch (Exception e) {
System.err.println("Error Receiving.");
System.err.println(e.getMessage());
System.exit(3);
}
}
}
}
class infoFromThread extends Thread {
ServerSocket s3;
Socket infoFromClientSocket = null;
public void run() {
try {
s3 = new ServerSocket(4446);
infoFromClientSocket = s3.accept();
} catch (Exception s3) {
System.exit(7);
}
while (true) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(infoFromClientSocket.getInputStream()));
String infoFromClient = in.readLine();
if (infoFromClient.contentEquals("10")) {
accept.setVisible(true);
sendinvite = 0;
} else if (infoFromClient.contentEquals("y")) {
chat.append("\n >Invite Accepted");
rps = true;
rock.setVisible(true);
paper.setVisible(true);
scissors.setVisible(true);
answerinvite = '-';
} else if (infoFromClient.contentEquals("n")) {
chat.append("\n\n >Invite Declined");
answerinvite = '-';
} else if (infoFromClient.contentEquals("1")) {
chat.append("\n\n >Opponent made selection");
P2pick = 1;
if (P1pick != 0) {
pt.start();
}
} else if (infoFromClient.contentEquals("2")) {
chat.append("\n\n >Opponent made selection");
P2pick = 2;
if (P1pick != 0) {
pt.start();
}
} else if (infoFromClient.contentEquals("3")) {
chat.append("\n\n >Opponent made selection");
P2pick = 3;
if (P1pick != 0) {
pt.start();
}
}
} catch (Exception e) {
System.err.println("Error Receiving Information.");
System.err.println(e.getMessage());
System.exit(3);
}
}
}
}
class infoToThread extends Thread {
ServerSocket s4;
Socket infoToClientSocket = null;
public void run() {
inputText = input.getText();
try {
s4 = new ServerSocket(4447);
infoToClientSocket = s4.accept();
} catch (Exception s4) {
System.exit(8);
}
while (true) {
try {
PrintWriter out = new PrintWriter(infoToClientSocket.getOutputStream(), true);
if (sendinvite == 10) {
out.println(sendinvite);
sendinvite = 0;
pauseInfo = false;
}
if ((answerinvite == 'y') || (answerinvite == 'n')) {
out.println(answerinvite);
answerinvite = '-';
}
if (winner == 1) {
out.println("Loser");
}
else if (winner == 2) {
out.println("Winner");
}
else if (winner == 3) {
out.println("Tie");
}
//winner = 0;
//System.err.println("infoToClient");
} catch (Exception e) {
System.err.println("Error Sending Information.");
System.err.println(e.getMessage());
System.exit(2);
}
}
}
}
class RPSpickTimer extends Thread {
public void run() {
while (true) {
try {
if (P1pick != 0) {
if (P1pick == 1) {
if (P2pick == 1) {
//tie
chat.append("\n\n Tie!");
winner = 3;
} else if (P2pick == 2) {
//P2wins
chat.append("\n\n " + user2 + " wins!");
winner = 2;
} else if (P2pick == 3) {
//P1wins
chat.append("\n\n " + user + " wins!");
winner = 1;
}
} else if (P1pick == 2) {
if (P2pick == 1) {
//P1wins
chat.append("\n\n " + user + " wins!");
winner = 1;
} else if (P2pick == 2) {
//tie
chat.append("\n\n Tie!");
winner = 3;
} else if (P2pick == 3) {
//P2wins
chat.append("\n\n " + user2 + " wins!");
winner = 2;
}
} else if (P1pick == 3) {
if (P2pick == 1) {
//P2wins
chat.append("\n\n " + user2 + " wins!");
winner = 2;
} else if (P2pick == 2) {
//P1wins
chat.append("\n\n " + user + " wins!");
winner = 1;
} else if (P2pick == 3) {
//tie
chat.append("\n\n Tie!");
winner = 3;
}
}
P1pick = 0;
P2pick = 0;
}
else {
sleep(250);
}
} catch (Exception e) {
System.err.println("Error Picking Winner.");
System.err.println(e.getMessage());
System.exit(2);
}
}
}
}
public static void main(String[] args) {
GUIserver s = new GUIserver();
}`
This line:
panel.add(chat);
Instead of adding chat, add pane, like:
panel.add(pane);
From JTextArea docs "The java.awt.TextArea internally handles scrolling. JTextArea is different in that it doesn't manage scrolling, but implements the swing Scrollable interface. This allows it to be placed inside a JScrollPane if scrolling behavior is desired, and used directly if scrolling is not desired."
I think that means that this is what you want:
JTextArea chat = new JTextArea(" Waiting to Start Client...");
JScrollPane chatScrollPane = new JScrollPane(chat);
...
panel.setLocation(300, 0);
panel.add(chatScrollPane);
panel.add(input);
As Nicolás Carlo pointed out, you already have the JScrollPane and just need to add it instead of the JTextArea. Basically the Java UI system (and most UI systems) are a giant tree of widgets. If you don't add a widget to the tree it doesn't have an effect. In this case, the JScrollPane wasn't getting added to the tree and therefore wasn't doing anything for you.
This is not an answer, but a demonstration of how a LayoutManager might be used to achieve the OP's results
So, based on your code example, I get this output...
I hope you note that the frame isn't big enough to hold the content, this is the major problem with null layouts, they never look the same on other systems...
And by utilising a GridBagLayout and a GridLayout and a concept known as "compound layouts", I was able to mock this...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ChatLayout {
public static void main(String[] args) {
new ChatLayout();
}
public ChatLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ChatPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ChatPane extends JPanel {
private JTextArea chatWindow;
private JTextField input;
private JLabel ipLabel;
private JButton rockBtn;
private JButton paperBtn;
private JButton scissorsBtn;
private JButton startBtn;
public ChatPane() {
JPanel leftPane = new JPanel(new GridBagLayout());
JPanel rightPane = new JPanel(new GridBagLayout());
chatWindow = new JTextArea(20, 40);
chatWindow.setText("Waiting to start chat...");
input = new JTextField(10);
ipLabel = new JLabel("IP...");
rockBtn = new JButton("Rock");
paperBtn = new JButton("Paper");
scissorsBtn = new JButton("Scissors");
startBtn = new JButton("Start");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1;
gbc.weightx = 1;
leftPane.add(new JScrollPane(chatWindow), gbc);
gbc.gridy++;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weighty = 0;
gbc.weightx = 1;
gbc.gridheight = 1;
leftPane.add(input, gbc);
gbc.gridy++;
gbc.fill = GridBagConstraints.HORIZONTAL;
leftPane.add(ipLabel, gbc);
JPanel buttonsPane = new JPanel(new GridLayout(3, 1));
buttonsPane.add(rockBtn);
buttonsPane.add(paperBtn);
buttonsPane.add(scissorsBtn);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.SOUTH;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weighty = 1;
rightPane.add(buttonsPane, gbc);
gbc.gridy++;
gbc.insets = new Insets(8, 0, 0, 0);
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weighty = 0;
gbc.gridheight = 2;
gbc.ipadx = 30;
gbc.ipady = 30;
rightPane.add(startBtn, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(leftPane, gbc);
gbc.gridx++;
gbc.weightx = 0;
gbc.weighty = 1;
add(rightPane, gbc);
}
}
}
Now, this is just an example. You needs might be different which would require using different layout managers or using them in different combinations...

Categories