I am fairly new to Java and Jung. I am writing a program where I need to add probabilities on edges of the event occurrence(means probability of the event that data will flow from first node to other). I am a little confuse that will Max-Flow do the trick for me or do I need to use some other option or there is no option to do it within Jung and in that case do I need to write it on my own? Any help in this regard will be appreciated.
regards,
waqas
Do you intend to set the edge weights to represent the probabilities of certain events? The Max-Flow algorithm will use the "capacities" you assign to each edge to find the path of maximum flow from the source vertex to the sink vertex. What exactly are you trying to do here?
I'm not very sure what your final aim is, so I'll try my best to help out.
You can first represent the probabilities by defining a custom Edge and Edge Factory classes. What I did was:
0. Imports:
import org.apache.commons.collections15.Factory;
1. Add in your custom classes. They custom edge class might be something like:
public static class MyEdge {
private int flow;
private int capacity;
private String name;
private int eIndex;
public MyEdge(String name, int eIndex) {
this.name = name;
this.eIndex = eIndex;
}
public int getCapacity() {
return this.capacity;
}
public void setCapacity(int edgeCapacity) {
this.capacity = edgeCapacity;
}
public int getFlow() {
return this.flow;
}
public void setFlow(int edgeFlow) {
this.flow = edgeFlow;
}
public String toString() {
return this.name;
}
}
The custom edge factory is what actually creates your edges each time you draw them on the canvas graphically, it might look like:
public static class MyEdgeFactory implements Factory {
private static int defaultFlow = 0;
private static int defaultCapacity = 0;
private int edgeCount;
private MyEdgeFactory() {
}
public MyEdge create() {
String name = "E" + edgeCount;
MyEdge e = new MyEdge(name, edgeCount);
edgeCount++;
e.setFlow(defaultFlow);
e.setCapacity(defaultCapacity);
return e;
}
}
2. Tell your visualization viewer how to display the edge labels; you'll need to add this in wherever you're creating your graph and VisualizationViewer object (vv):
vv.getRenderContext().setEdgeLabelTransformer(new Transformer() {
public String transform(MyEdge e) {
return (e.toString() + " " + e.getFlow() + "/" + e.getCapacity());
}
});
Now everytime you create an edge, it's label will be of the form "E0 0/0", "E1 0/0" and so on.
I'll be posting detailed tutorials and code on my blog soon so you could watch that space if you're going to be spending significant time on whatever project you're working on.
Look at the way you're calling setEdgeLabelTransformer, you need to pass it a new Transformer(), like I've done in my code snippet numbered 2.
When you pass a new ToStringLabeller(), you're telling the viewer to label using the toString() method of the edge object. You'll need to pass a custom Transformer instead, just correct your code to look like mine and you'll be fine.
Related
I decided to create an account in order to ask a question I cant seem to figure out myself, or by some googling, hopefully I didn't just overlook it.
Essentially I am trying to make a text adventure game in Java, and am having a little trouble seeing how I should relate everything in the idea of objects. I have been successful in using XML stax and sending a file to the program, and using attributes and what not, to make it where the user can enter an integer associated with an option, and see if option requires an "item" or gives them an Item. I however did not take an OOP to this.
I want my new program to people able to take a string of user input in, instead of only an integer, and checking it against an array list if it exists. This is closer to the classic MUDs most may be familiar with.
I want to design it in a modular way, so I can slowly add on ideas, and more complexity to go along, so I don't want a "well it works so lets leave it alone" approach either.
Currently I simply want something close to this:
A Room object, which would have: an ID, Description, and interact-able
a Choice object (this one im not sure on) I thought about making an object to hold each rooms possible choices, both for exit, and for interact-ables
if so, the room object may need a Choice Object.
I've thought it over, tried some code, thought it over again, and every time, I keep ending up hard coding more than I feel I should, and making tons more variables than I feel are necessary, which makes me feel like i'm missing something crucial in my thinking.
I also want these rooms to be created through an inputted file, not generated in the code (so essentially the code is a story reader/crafter for any type, not one)
I have also been attempting this too long, and my solutions are becoming worse, but below was my most recent attempt at a rough Idea:
a GameManager class that takes the userInput and checks it some, before passing it along. I havent passed any data because im not sure of the approach. also im not used to regex, so some of that may also be wrong, if it is, maybe point it out, but that is not my focus
import java.util.Scanner;
public class GameManager {
private static final String EXIT_PHRASE = "exit";
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
String userStringVal = "";
while(!userStringVal.equals(EXIT_PHRASE)){
userStringVal= userInput.nextLine();
if(checkKeywords(userStringVal)){
System.out.println("matches keyword");
}
else System.out.println("didnt match a keyword");
}
userInput.close();
}
public static boolean checkKeywords(String string){
boolean isKeyword = false;
string.toLowerCase();
if(string.matches("travel.*") || string.matches("search.*")){
System.out.println("passed first check");
String substring = string.substring(6);
if(matchDirection(substring)){
isKeyword = true;
}
}
return isKeyword;
}
public static boolean matchDirection(String string){
boolean hasDirection = false;
if(string.matches(".*\\bnorth|south|east|west|northeast|northwest|southeast| southwest|up|down")){
hasDirection = true;
}
return hasDirection;
}
}
The Room object I thought about as such:
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
public class Room {
private String roomDescription = "";
private int roomID=0;
private int northExit=0;
private int southExit=0;
private int eastExit=0;
private int westExit=0;
private int northeastExit=0;
private int northwestExit=0;
private int southeastExit=0;
private int southwestExit=0;
private int upExit=0;
private int downExit=0;
private String[] interactables = new String[10];
private Options options = new Options();
public Room(XMLStreamReader reader) throws XMLStreamException{
setAttValues(reader);
setRoomDescription(reader);
setUpOptions();
}
public void setinteractables(XMLStreamReader reader){
int count = reader.getAttributeCount();
for(int i = 0; i < count; i++){
interactables[i] = reader.getAttributeValue(i);
}
}
public void setAttValues(XMLStreamReader reader){
int count = reader.getAttributeCount();
for(int i = 0; i < count; i++){
String att = reader.getAttributeLocalName(i);
if(att !=""){
switch(att){
case "North": northExit=Integer.parseInt(att);
case "South": southExit=Integer.parseInt(att);
case "East": eastExit=Integer.parseInt(att);
case "West": westExit=Integer.parseInt(att);
case "NorthEast": northeastExit=Integer.parseInt(att);
case "NorthWest": northwestExit=Integer.parseInt(att);
case "SouthEast": southeastExit=Integer.parseInt(att);
case "SouthWest": southwestExit=Integer.parseInt(att);
case "Up": upExit=Integer.parseInt(att);
case "Down": downExit=Integer.parseInt(att);
case "ID": roomID=Integer.parseInt(att);
}
}
}
}
public void setRoomDescription(XMLStreamReader reader) throws XMLStreamException{
roomDescription = reader.getElementText();
}
public void setUpOptions(){
options.setCardinalPointers(northExit, southExit, eastExit, westExit);
options.setIntercardinalPointers(northeastExit, northwestExit, southeastExit, southwestExit);
options.setElevationPointers(upExit, downExit);
}
}
what can I do to make sure I dont have to state so many directions with so many variables?
here is a quick and rough idea of an Option class that I thought about, but i didn't finish deciding I am already too far in the wrong direction
public class Options {
private int northPointer = 0;
private int southPointer= 0;
private int eastPointer = 0;
private int westPointer = 0;
private int northeastPointer= 0;
private int northwestPointer = 0;
private int southeastPointer = 0;
private int southwestPointer = 0;
private int upPointer = 0;
private int downPointer = 0;
private String northInteractable = "";
private String southInteractable = "";
private String eastInteractable = "";
private String westInteractable = "";
private String northeastInteractable ="";
private String northwestInteractable = "";
private String southeastInteractable = "";
private String southwestInteractable = "";
private String upInteractable = "";
private String downInteractable = "";
public Options(){
}
public void setCardinalPointers(int north, int south, int east, int west){
northPointer = north;
southPointer = south;
eastPointer = east;
westPointer = west;
}
public void setIntercardinalPointers(int northeast, int northwest, int southeast, int southwest){
northeastPointer = northeast;
northwestPointer=northwest;
southeastPointer=southeast;
southwestPointer=southwest;
}
public void setElevationPointers(int up, int down){
upPointer = up;
downPointer = down;
}
public String whatToReturn(String string){
String importantPart = "";
if(string.matches("travel.*")){
String substring = string.substring(6);
}
else {
importantPart = "Interactable";
String substring = string.substring(6);
if (substring.matches("\\bnorth\\b")) {
if(northInteractable!=0){
}
}
else if (substring.matches("\\bsouth\\b"))
else if (substring.matches("\\beast\\b"))
else if (substring.matches("\\bwest\\b"))
else if (substring.contains("northeast"))
else if (substring.contains("northwest"))
else if (substring.contains("southeast"))
else if (substring.contains("southwest"))
else if (substring.contains("up"))
else if (substring.contains("down"))
}
return importantPart;
}
}
I did not see the adventure tag until after I typed this, so I will start perusing through there, but will still post this, so my apologies if there is a good answer to this and I have yet to find it.
as a recap: what would be a good way to relate a few objects to create a room object (that gets its information from a file (XML being what im used to)) having exits, descriptions, and interactions. and the user interacting with these based off keywords that can be inputted freely, and not restricted to say, index values of array's holding keywords.
Im thinking when the user types something like "travel north" to first check if they typed a keyword, in this case being travel, then a direction. Then somewhree else checking if it states travel, check north with a possible northExit a room may or may not have. Then if its another keyword, say like check, to make it easy also have the exact same directions, but check for a different string.
Then if room "northExit" exists, get an option somehow, with a pointer to another roomID. though This thought process causes me issues when thinking about future possibility of requiring items for getting to the next room. Also where to store/acquire these options is causing some difficulties.
There are two things I would like to introduce to you. The first, in the enum. You can think of this as a special kind of class where all the possible options are enumerated in the class definition. This is perfect for things like, in your case, directions. Enums can be simple, where you just list all of the possible options for use in other classes:
public enum Direction {
NORTH, NORTH_EAST, EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NOTH_WEST;
}
They can be a bit more complex, if you want them to have methods and attributes of their own:
public enum Direction {
NORTH(true), NORTH_EAST(false), EAST(true), SOUTH_EAST(false), SOUTH(true), SOUTH_WEST(false), WEST(true), NOTH_WEST(false);
private final boolean isCardinal;
private Direction(boolean isCardinal){
this.isCardinal = isCardinal;
}
public boolean isCardinal(){
return isCardinal;
}
public static Collection<Direction> getCardinalDirections(){
return Arrays.asList(Direction.values()).stream().filter(Direction::isCardinal).collect(Collectors.toList());
}
public static Collection<Direction> getIncardinalDirections(){
return Arrays.asList(Direction.values()).stream().filter(x -> !x.isCardinal()).collect(Collectors.toList());
}
}
Please read more about Java enum types here.
The second thing I would like to introduce to you is the data structure known as the Map. Maps are also known as Dictionaries, and that can often help understanding how they work. A Map will take one object and map it to another object, like how a Dictionary maps a word to its definition, or a phonebook maps a person's name to their phone number. We can simplify your Room class a ton by using a Map. I am not going to reproduce all of your code, since I'm focusing on your Room exists right now:
public class Room {
private Map<Direction, Room> exits;
public Room(){
this.exits = new HashMap<>();
}
public void setExit(Direction direction, Room room){
this.exits.put(direction, room);
}
public Room getExit(Direction direction){
return this.exits.get(direction);
}
}
Please read more about the Java Map interface here.
You will, of course, need to adapt your methods which are reading from XML, etc. But, now, your Room class should be greatly simplified.
I hope this points you in a helpful direction.
I'm currently working on a Bukkit plugin to claim custom areas, and I'm using rectangles (and .intersect()) to check if regions overlap before creating a claim.
I'm trying to figure a way where I don't need to check every single existing claim (of which there eventually will be tens of thousands) as surely this will take quite some time. I'll also need to check for claim owners when players do things such as break blocks or place blocks.
In my current system (which doesn't allow custom claim sizes, only squares) I only need to check at most about 10 claims because I can detect claims within the vicinity of the claim (at most 64 blocks away which is the max radius of claims in this system) but now the claim sizes can be infinitely large in theory with the new system.
Is checking all the rectangles going to take a massive amount of time? Am I being dumb, is there a way to check for rectangles within the vicinity even while the size is unlimited?
First of all checking thousands of rectangles is not gonna be a big deal for java(or your Plugin). Its simple math and should be done in millisecs. To deal with your owner Problem i would recommend you to create my own rectangle and owner class. So your rectangle can have a defined owner and you can simply check if the player is the owner of the area he is in right now.
public class custom_Area extends Rectangle{
private owner o;
public owner getOwner() {
return o;
}
public void setOwner(owner o) {
this.o = o;
}
}
EDIT:
I just tested it by creating 100.000 random rectangles and checking if one of them intersects with others.
--Custom rectangle class
public class area extends Rectangle{
private owner o;
public area(owner o, int i, int i1, int i2, int i3) {
super(i, i1, i2, i3);
this.o = o;
}
public owner getO() {
return o;
}
public void setO(owner o) {
this.o = o;
}
}
--Custom owner class
public class owner {
String name;
public owner(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
--Main class
public class Rectanglesearch {
public static area a[] = new area[100000];
public static owner o[] = new owner[10];
public static int intersectCounter = 0;
public static int ownerCounter = 0;
public static void main(String[] args) {
for(int y = 0; y<10;y++){
o[y] = new owner("y");
}
for (int i = 0; i < 100000; i++) {
a[i] = new area(o[(int)(Math.random() * 10)],random(),random(),random(),random());
}
checkArea(a[10]);
checkOwner(o[3]);
System.out.println("Area a[10] intersects with "+intersectCounter+" out of "+a.length);
System.out.println("Owner o[3] owns "+ownerCounter+" areas out of "+a.length);
}
public static int random(){
return (int)(Math.random() * 100000) + 1;
}
public static void checkArea(area ab){
for (area a1 : a) {
if (ab.intersects(a1)) {
intersectCounter +=1;
}
}
}
public static void checkOwner(owner ob){
for (area a1 : a){
if(a1.getOwner()==ob){
ownerCounter +=1;
}
}
}
}
method checkArea(area ab) returns you how man areas intersects with area ab
method checkOwner(owner ob) return you how man areas are owned my ob
Consider storing your rectangles in an acceleration structure such as a quadtree. To test a new rectangle against the existing set, you'd navigate down the tree to the node that would contain it, testing against the rectangles in each node along the way, but ignoring the rectangles in all the nodes you don't traverse. This quickly eliminates lots of rectangles that can't possibly intersect the new one, without having to test each one individually.
Other acceleration structures are also possible as alternatives, such as binary space partitioning. Read about spatial indexes for a list of several others that may be relevant.
Adding new rectangles to the set doesn't happen very often, so performance probably isn't a big concern. But I'd imagine that your plugin also needs to check whether a specific coordinate (such as a block) is within one of the claimed regions, and that may happen much more often — potentially every frame — so it really does need to be fast. A quadtree or other acceleration structure will be valuable for that.
I've currently been learning and programming pathfinding(in Java) using the A* algorithm. A problem I've run into is when multiple entities are trying to pathfind, they both alter the previousNode(the Node that the Node being calculated on came from), messing up the algorithm, and eventually Node A will point to Node B and Node B will point to Node A.
How can I change the algorithm to either
Not use this previousNode system that is littered throughout all of the A * algorithms(that I have seen, that is)
Alter this system to be used concurrently
I am trying to avoid having one entity finish pathfinding, then telling the next entity to pathfinding, and so on. Like doing a wait() - notify() pair in Java.
public Path findPath(int startX, int startY, int goalX, int goalY) {
//Path is basically just a class that contains an ArrayList,
//containing Nodes, which contains the steps to reach a goal.
if(map.getNode(goalX, goalY).isObstacle()) {
return null;
}
map.getNode(startX, startY).setDistanceFromStart(0);
closedList.clear();
openList.clear(); //A List with added getFirst() - gets the first Node in the list
openList.add(map.getNode(startX, startY));
while(openList.size() != 0) {
//Node contains a List that has all of the Nodes around this node, a
//F, G, and H value, and its row(y) and column(x)
Node current = openList.getFirst();
if(current.getX() == goalX && current.getY() == goalY) {
return backtrackPath(current);
}
openList.remove(current);
closedList.add(current);
for(Node neighbor : current.getNeighborList()) {
boolean neighborIsBetter;
//If I've already searched this neighbor/node, don't check it
if(closedList.contains(neighbor)) {
continue;
}
if(!neighbor.isObstacle()) {
float neighborDistanceFromStart = (current.getDistanceFromStart() + map.getDistanceBetween(current, neighbor));
if(!openList.contains(neighbor)) {
openList.add(neighbor);
neighborIsBetter = true;
} else if(neighborDistanceFromStart < current.getDistanceFromStart()) {
neighborIsBetter = true;
} else {
neighborIsBetter = false;
}
if(neighborIsBetter) {
neighbor.setPreviousNode(current);
neighbor.setDistanceFromStart(neighborDistanceFromStart);
neighbor.setHeuristic(getManhattanDistance(neighbor.getX(), neighbor.getY(), goalX, goalY));
}
}
}
}
return null;
}
public Path backtrackPath(Node fromNode) {
Path path = new Path();
while(fromNode.getPreviousNode() != null) {
path.prependWaypoint(fromNode);
fromNode = fromNode.getPreviousNode();
}
return path;
}
I am specifically talking about(within findPath())
if(neighborIsBetter) {
neighbor.setPreviousNode(current); //previousNode is a value in the Node class that points to the Node that it came from
neighbor.setDistanceFromStart(neighborDistanceFromStart);
neighbor.setHeuristic(getManhattanDistance(neighbor.getX(), neighbor.getY(), goalX, goalY));
}
I don't think you can do A* (or any pathfinding algorithm, for that matter) without somehow storing a backpointer for a given path. So that leaves you with two options
Require each agent (Thread, I assume) to create their own copy of the graph to work on. That way each A* call going on won't interfere with one another, as they are working with the fields of the same node on different graphs.
Change your A* code to be able to handle multiple concurrent calls.
Option 1 is fairly self-explanatory and probably the better option. If this is just for you, you should probably just go with that one (instead of trying to make A* fully concurrent on a single graph). This would entail adding map as an input parameter (and requiring that concurrent calls should use a different map instance, either throwing an exception or having unspecified behavior if that doesn't occur). Additionally, you should instantiate closedList and openList as new data structures in each call, rather than share a list.
If that's not to your liking - you really want to fully encapsulate the mutli-call usage into the method itself, I think the simplest way you could do this is require an additional parameter of an id - some unique string that is guaranteed not to be the same as the id of another concurrent call. So the header of A* now looks like:
public Path findPath(final String ID, int startX, int startY, int goalX, int goalY) {
From there, change all of the implementations of each of the settable pathfinding fields in Node to a HashMap with the id as the key. From your code, I'm going to guess that your Node class looks something like this:
public class Node{
//Fields used by the A* call - no problem here
private boolean obstacle;
//Fields *edited* by the A* call
private float distanceFromStart;
private Node previous;
private int heuristic;
//other fields and stuff
public boolean isObstacle(){
return obstacle;
}
public float getDistanceFromStart(){
return distanceFromStart;
}
public void setDistanceFromStart(float f){
distanceFromStart = f;
}
public Node getPrevious(){
return previous;
}
public void setPrevious(Node p){
previous = p;
}
public int getHeuristic(){
return heuristic;
}
public void setHeuristic(int h){
heuristic = h;
}
}
We can edit the edited fields to be able to store many values, by id, as such:
public class Node{
//Fields used by the A* call - no problem here
private boolean obstacle;
//Fields *edited* by the A* call
private HashMap<String,Float> distanceFromStart;
private HashMap<String,Node> previous;
private HashMap<String,Integer> heuristic;
//other fields and stuff
public boolean isObstacle(){
return obstacle;
}
public float getDistanceFromStart(String id){
return distanceFromStart.get(id);
}
public void setDistanceFromStart(String id, float f){
distanceFromStart.put(id, f);
}
public Node getPrevious(String id){
return previous.get(id);
}
public void setPrevious(String id, Node p){
previous.put(id,p);
}
public int getHeuristic(String id){
return heuristic.get(id);
}
public void setHeuristic(String id,int h){
heuristic.put(id,h);
}
}
From there, simply edit your A* method to give the id from the method call to the getters and setters when called for. So long as two concurrent method calls don't have the same id value, they won't interfere with each other. Three things to keep in mind for this to work correctly:
Make sure that every editable field gets this treatment. It won't work if you forget about one. Non-editable fields (fields that don't get altered as a byproduct of running A*) can stay singular.
If you use the the above, you should probably add to the cleanup stage a step of removing all the information for the given ID from the graph, or the nodes' hashmaps will grow larger with each call.
Either way, you still should make openList and closedList new local instances, no matter what concurrent approach you pick. There's nothing to gain from making openList and closedList shared instances, and only bugs can come of it.
List<Node> closedList = new LinkedList<Node>();
List<Node> openList = new LinkedList<Node>();
//Don't have to clear them anymore - they're new lists
openList.add(map.getNode(startX, startY));
I have an SparseMultigraph< Node, Edge > g where edges have two attributes:
int weight;
ArrayList<Date> time;
I would like to filter the graph according to weight and time independently. Say I start filtering out according to weight using a JSlider called weightSlider (I am in Netbeans and Swing):
private void weightSliderMouseReleased(java.awt.event.MouseEvent evt) {
// filter network according to weight:
Predicate<Edge> edgeAboveWeight = new Predicate<Edge>() {
#Override
public boolean evaluate(Edge e) {
return e.getWeight() >= weightSlider.getValue();
}
};
EdgePredicateFilter<Node, Edge> edgePredicateFilter = new EdgePredicateFilter<>(edgeAboveWeight);
Graph<Node, Edge> transform = edgePredicateFilter.transform(g);
}
My question is: how do I push the new graph in the visualization, preserving the node position?
Since it is the first time I attempt to do something like that, I might have missed a simpler way to achieve my goal, so any suggestion is more than welcome!
EDIT: I succeeded to implement this with:
private void weightSliderMouseReleased(java.awt.event.MouseEvent evt) {
// filter network according to weight:
Predicate<Edge> edgeAboveWeight = new Predicate<Edge>() {
#Override
public boolean evaluate(Edge e) {
return e.getWeight() >= weightSlider.getValue();
}
};
EdgePredicateFilter<Node, Edge> edgePredicateFilter = new EdgePredicateFilter<>(edgeAboveWeight);
Graph<Node, Edge> transform = edgePredicateFilter.transform(g);
layout.setGraph(transform);
vv.validate();
vv.repaint();
}
Still don't know if it's the most efficient way, but it works...
If you want to filter the actual data, then what you're doing is fine.
If what you want to do is just filter the edges whose weight is below a certain value from being rendered, then you can tell the PluggableRendererContext that directly:
http://jung.sourceforge.net/doc/api/edu/uci/ics/jung/visualization/PluggableRenderContext.html#setEdgeIncludePredicate(org.apache.commons.collections15.Predicate)
This is demonstrated in PluggableRendererDemo.
I came across an interview question asking to design a word processor.
After my research I found Flyweight design pattern as an approach. I came up with below code (ignore syntax). But I am having hard time thinking of what will be my key and what will be my value for word processor.
public class Format
{
public readonly string _fontname;
public readonly string _weight;
public readonly int _size;
public Format(string fontname, string weight, string size)
{
_fontname = fontname;
_weight = weight;
_size = size;
}
}
public class TextFromatInfo
{
public _readonly Format _oFormat
public TextFormatInfo ( Format oformat)
{
_oFormat = oFormat;
}
public Format GetFormat
{
get {return this._oFormat}
}
public void ApplyFormat(format Format)
{
console.writeline ("apply format fontname: " format.forntname +
"size: " + format.size + "weight : " format.weight
}
}
public class TextFormatFactory
{
public readonly IDictionary<Format, TextFormatInfo> _cache =
new Dictionary <Format, TextFormatInfo>
public TextFormatInfo GetTextFormatInfo(Format oFormat)
{
if (_cache.ContainsKey(oFormat)) return _cache[oFormat];
var OTextFormatInfo= new TextFormatInfo(oFormat);
_cache.add(OTextFormatInfo.GetFormat, OTextFormatInfo);
return OTextFormatInfo ;
}
}
public class TestFlyWeight
{
private static TextFormatInfo[] formtInfo = new TextFormatInfo[100];
private static TextFormatFactory ff;
public void ProcessesWord(char c, string fontname, int size, string weight)
{
}
}
How would the above class look like? How can I complete the program by actually processing word?
Honestly I think they were maybe not so much interested in patterns as in architecture. But you might have given sufficient material for them to digest.
I would say MDI is a key topic here: multiple document interface. Multiple tabs with several documents.
Having one Document object per file system file (twice opening the same file), and possibly having several DocumentViews (swing: JTextPanes) per Document, bridged by the DocumentListener. In different tabs or in a vertically split single tab, so you may scroll to another spot and still remain at the first spot in split panes. _Specially stress, that this is se
Maybe building swing's EditorKit and StyledDocument.
So to make points of UI knowlegde, creativity, features, existing classes.
This all said, Patterns are an important asset in interviews too, I have experienced.