Categories
discuss

Java MVC – How to divide a done text game into MVC?

Been sitting here for hours now trying to figure this out, so a bit sympathy for this large question. 🙂

The Goal: I simply want to divide my done code into MVC (Model View Controller) parts. I have the game logics done and text based – the code works fine.

The Problem: Well, I want to implement this code into MVC, but where do explain for the MODEL that it should use text-based? Because the VIEW is only for the layout (graphically) correct? I am having a REALLY hard time figuring out where to begin at all. Any pointers would be so nice!

Here is my game logics code:

import mind.*;
import javax.swing.*;
import java.util.*;
import java.lang.*;
import java.awt.*;

public class Drive {
String[] mellan;
boolean gameEnd, checkempty, checkempty2, enemy, enemy2;
String gr,rd,tom;
int digits;

public Drive() {
    // Gamepieces in textform
    gr="G"; rd="R"; tom=" ";


    mellan = new String[7];
    String[] begin = {gr,gr,gr,tom,rd,rd,rd};
    String[] end = {rd,rd,rd,tom,gr,gr,gr};

    //input
    Scanner in = new Scanner(System.in);

    mellan=begin;
    gameEnd=false;
    while (gameEnd == false) {
        for(int i=0; i<mellan.length; i++) {
            System.out.print(mellan[i]);
        }
        System.out.print("        Choose 0-6: ");

        digits = in.nextInt();
        move();
        checkWin();
    }
}

void move() {
    //BOOLEAN for gameruls!!!
    checkempty = digits<6 && mellan[digits+1]==tom;
    checkempty2 = digits>0 && mellan[digits-1]==tom;
    enemy = (mellan[digits]==gr && mellan[digits+1]==rd &&     mellan[digits+2]==tom);
    enemy2 = (mellan[digits]==rd && mellan[digits-1]==gr && mellan[digits-2]==tom);

    if(checkempty) {
        mellan[digits+1]=mellan[digits];
        mellan[digits]=tom;
    } else if (checkempty2) {
        mellan[digits-1]=mellan[digits];
        mellan[digits]=tom;
    } else if (enemy) {
        mellan[digits+2]=mellan[digits];
        mellan[digits]=tom;
    } else if (enemy2) {
        mellan[digits-2]=mellan[digits];
        mellan[digits]=tom;
    }
}

void checkWin() {
    String[] end = {rd,rd,rd,tom,gr,gr,gr};
    for (int i=0; i<mellan.length; i++){
    }
    if (Arrays.equals(mellan,end)) {
        for (int j=0; j<mellan.length; j++) {
            System.out.print(mellan[j]);
        }
        displayWin();
    }
}

void displayWin() {
    gameEnd = true;
    System.out.println("nNicely Done!");
    return;
}

// Kör Drive!
public static void main(String args[]) {
    new Drive();
}
}

Here is how I defined my DriveView thus far: (just trying to make one button to work)

import mind.*;
import javax.swing.*;
import java.util.*;
import java.lang.*;
import java.awt.*;
import java.awt.event.*;

public class DriveView extends JFrame {
JButton ruta1 = new JButton("Green");
JButton ruta2 = new JButton("Green");
JButton rutatom = new JButton("");
JButton ruta6 = new JButton("Red");
private DriveModel m_model;

public DriveView(DriveModel model) {
    m_model = model;

    //Layout for View
    JPanel myPanel = new JPanel();
    myPanel.setLayout(new FlowLayout());
    myPanel.add(ruta1);
    myPanel.add(ruta2);
    myPanel.add(rutatom);
    myPanel.add(ruta6);
    this.setContentPane(myPanel);
    this.pack();
    this.setTitle("Drive");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

void addMouseListener(ActionListener mol) {
    ruta2.addActionListener(mol);
}

}

And DriveController which gives me error at compile

import mind.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.*;

public class DriveController {
private DriveModel m_model;
private DriveView m_view;

public DriveController(DriveModel model, DriveView view) {
    m_model = model;
    m_view = view;

    view.addMouseListener(new MouseListener());
}

class MouseListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        String mening;
        mening = e.getActionCommand();
        if (mening.equals("Green")) {
            setForeground(Color.red);
        }
    }
}

}

Answer

Your game model can have more than one view: a GUI view, a console view, a status view, etc. Typically each view arranges to listen for changes in the model, and it then queries the model for the information it needs to render it’s particular view. This simple game was designed specifically to illustrate the concepts. The section named “Design” elaborates in more detail.

Addendum: This outline corresponds roughly to this architecture, symbolized below.

MVC diagram

public class MVCOutline {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            //@Override
            public void run() {
                new MVCOutline().create();
            }
        });
    }

    private void create() {
        JFrame f = new JFrame("MVC Outline");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new MainPanel());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class MainPanel extends JPanel {

    public MainPanel() {
        super(new BorderLayout());
        Model model = new Model();
        View view = new View(model);
        Control  control = new Control(model, view);
        this.add(view, BorderLayout.CENTER);
        this.add(control, BorderLayout.WEST);
    }
}

class Control extends JPanel implements ... {

    private Model model;
    private View view;

    public Control(Model model, View view) {
        this.model = model;
        this.view = view;
    }
}

class View extends JPanel implements Observer {

    private Model model;

    public View(Model model) {
        this.model = model;
        model.addObserver(this);
    }

    public void update(Observable o, Object arg) {
        // update GUI based on model
    }
}

class Model extends Observable {

    public void next() {
        this.notifyObservers(...);
    }
}
Categories
discuss

What is the accepted way to replace java.util.Date(year,month,day)

I’m trying to do something really simple, but starting to realize that dates in Java are a bit of minefield. All I want is to get passed groups of three ints ( a year, a month and a date) create some Date objects, do some simple test on them (along the lines of as date A before date B and after January 1 1990), convert them to java.sql.Date objects and pass them off to the database via JDBC.

All very simple and works fine using the java.util.Date(int year,int month,int day) constructor. Of course that constructor is depreciated, and I’d like to avoid using depreciated calls in new code I’m writing. However all the other options to solve this simple problem seem stupidly complicated. Is there really no simple way to do what I want without using depreciated constructors?

I know the standard answer to all Java date related questions is “use joda time”, but I really don’t want to start pulling in third party libraries for such a seemingly trivial problem.

Answer

The idea is to use the Calendar class, like so:

Calendar cal = Calendar.getInstance();
cal.set(year, month, date);
Date date = cal.getTime();

Indeed, if you check the Javadoc of the constructor you are mentioning, it is exactly what is suggested:

Date(int year, int month, int date)
          Deprecated. As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date) or GregorianCalendar(year + 1900, month, date).

Or … use JodaTime :-).

Categories
discuss

Scrollbars on JTextArea in a JScrollPane do not work

I’m having trouble getting a JTextArea to scroll. I’m not sure how you can mess up a JScrollPane but I seem to have and I just can’t see it. It’s all part of a larger project but the code below is how I’m creating a JTextArea and adding it to a JScrollPane. When you type beyond the edge of the text area the scrollbar doesn’t appear. Setting the vertical scrollbar to always on gives a scrollbar that doesn’t do anything.

import javax.swing.*;
import java.awt.*;

public class TextAreaTest extends JFrame{

    public TextAreaTest() {
     super("Text Area Scroller");

     Container c = getContentPane();

     JTextArea textarea = new JTextArea();
     textarea.setPreferredSize(new Dimension(300, 50));
     textarea.setLineWrap(true);
     textarea.setText("xxnxxnxxnxxnxxnxxnxxnxxnxxnxxnxxnxxnxxnxxn");

     JScrollPane scroller = new JScrollPane(textarea);

     c.add(scroller, BorderLayout.CENTER);
     pack();
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String args[]){
     TextAreaTest instance = new TextAreaTest();
     instance.setVisible(true);
    }
}

I’ve tried setting the text area text, or rows and columns, in the constructor, neither of which worked. It’s doing my head in. Any ideas?

Answer

Set the preferred size of the scroll pane rather than the text area.

Categories
discuss

Split string into sentences

I have written this piece of code that splits a string and stores it in a string array:-

String[] sSentence = sResult.split("[a-z]\.\s+");

However, I’ve added the [a-z] because I wanted to deal with some of the abbreviation problem. But then my result shows up as so:-

Furthermore when Everett tried to instruct them in basic mathematics they proved unresponsiv

I see that I lose the pattern specified in the split function. It’s okay for me to lose the period, but losing the last letter of the word disturbs its meaning.

Could someone help me with this, and in addition, could someone help me with dealing with abbreviations? For example, because I split the string based on periods, I do not want to lose the abbreviations.

Answer

Parsing sentences is far from being a trivial task, even for latin languages like English. A naive approach like the one you outline in your question will fail often enough that it will prove useless in practice.

A better approach is to use a BreakIterator configured with the right Locale.

BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US);
String source = "This is a test. This is a T.L.A. test. Now with a Dr. in it.";
iterator.setText(source);
int start = iterator.first();
for (int end = iterator.next();
    end != BreakIterator.DONE;
    start = end, end = iterator.next()) {
  System.out.println(source.substring(start,end));
}

Yields the following result:

  1. This is a test.
  2. This is a T.L.A. test.
  3. Now with a Dr. in it.
Categories
discuss

Try to use Window.FEATURE_CUSTOM_TITLE but got Exception:You cannot combine custom titles with other title feature..

I am trying to use a custom title to include an image button to the title bar. I got a lot of help form this post: android: adding button to the title of the app?, but could not get it work for my ListActivity.

In a nutshell, following is what I have:

  1. I hide the titlebar in the AndroidManifest.xml
  2. The specify a relative layout for the custom title (workorder_list_titlebar.xml)

  3. My Activity Class looks like the following:

    public class WorkOrderListActivity extends ListActivity {
     String[] orders={"WO-12022009", "WO-12302009","WO-02122010", "02152010"};
     @Override
     public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);   
       requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
       this.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.workorder_list_titlebar);
       setContentView(R.layout.workorder_list);
       setListAdapter(new ArrayAdapter(this,R.layout.workorder_list, R.id.label,orders));    
            }
    }

When I ran the app, I got AndroidRuntimeException: You cannot combine custom titles with other title features.

Base on the stack trace, the exception was thrown by com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:183), that was triggered by setlistAdapter call.

Does anyone have the same problem with ListActivity? Also once I manage to get this work, how do I attach listeners to the image button for it to do something?

Thanks in advance.

Answer

I had the same issue and I fix it deleting

<item name="android:windowNoTitle">true</item>

from my theme.xml

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..