Lab 10: ArrayLists and Files in a GUI Application
For this lab, you will work on a simple GUI application. The
starting point for your work consists of four files (TextCollage,
DrawTextItem, DrawTextPanel, and SimpleFileChooser) in the code
directory. These files are supposed to be in package named
"textcollage". Start an Eclipse project, create a package
named textcollage in that project, and copy the four files
into the package. To run the program, you should run the
file TextCollage.java, which contains the main routine.
You will need to look through the DrawTextItem.java and
SimpleFileChooser.java, but the only file that you have to
edit is DrawTextPanel.java.
Part 1: ArrayLists
You can run TextCollage to see what it does. As it
stands, you can click the drawing area to place a string on the
canvas. The text of the string comes from the input box at the
bottom of the window. The program only has support for one string.
If you click the mouse again, the previous string disappears, and
the string appears at the location of the new mouse click.
A string in the program is represented by a variable of type
DrawTextItem. In addition to the string itself, a
DrawTextItem holds information about the appearance of the
string, such as its color, font, background color, rotation, and
whether it has a border. (The doMousePress method, where
strings are created, has some lines that you can uncomment to
experiment with these options.)
Your first job is to replace the variable theString, which
is a single DrawTextItem, with a variable of type
ArrayList<DrawTextItem> that can hold any number of
text items.
You will then have to modify the program wherever
theString was used. For example, in the
doMousePress method, you should add the
newly created DrawTextItem variable to the arraylist,
instead of assigning it to theString.
When you have finished, you should be able to add multiple strings
to the picture, and the "Undo" and "Clear" commands in the "Edit"
menu should work. (The "Save Image" command in the "File" menu and
the commands in the "Options" menu also work, but they were already
working before you made any changes.)
Part 2: Files
The program is already able to save the contents of the drawing
area as an image. But when you do this, there is no way to go back
and edit the strings in the picture. To be able to do that, you
should save all the information that defines the strings, not just
the image where the strings are displayed. That's what the "Save"
and "Open" commands are for in the "File" menu. The "Save" command
should create a text file that describes the contents of the image
(that is, the background color and the arraylist of
DrawTextItems). The "Open" command should be able to read
a file created by the "Save" command and restore the state of the
program. You can look at the implementation of the "Save Image"
command for some hints. Note in particular the use of try..catch to
catch any exceptions that occur during the file manipulation; you
should always do something similar when you work with files, and
you should report any errors to the user.
First, implement the "Save" command. Use the method
fileChooser.getOutputFile to get a File from the user.
(fileChooser is a varialble of type
SimpleFileChooser, which is already defined. See the
implementation of "Save Image" for an example of using it.) Create
a PrintWriter to write to the file. Output a text
representation of the background color of the image, then write at
least the text and color of each DrawTextItem in the
arraylist. Don't forget to close the PrintWriter.
Note that you can represent a color c as the three integers
c.getRed(), c.getGreen(), and c.getBlue(). Design
the format for your output file so that it will be easy to read the
data in later. Putting every output value on a separate line is the
easiest approach. Test your work by saving a file
and looking at its contents.
Next, you can implement the "Open" command. Use the method
fileChooser.getInputFile to let the user select a file for
input. Create a Scanner to read from the file. You should use the
scanner to read the contents of the file back into the program and
reconstruct the picture represented by the contents of the file. Of
course, this will only succeed if the file is one that was
previously saved from the program using the Save command (or if it
follows exactly the same syntax as such a file). Note: As long as
each item is on its own line in the file, you can use
scanner.nextLine() to read items from the file. If you are
trying to read an integer, use
Integer.parseInt(scanner.nextLine()). You should know the
order in which the data items were written, and you should read
them in the same order. If any error occurs, it means that the file
is not of the correct form. Don't forget to call canvas.repaint()
at the end, to make the new image visible. Ideally, if an
error does occur, you should not change the current contents of the
image.
Part 3: Improve the program!
To complete your program, you should design at least one
additional feature and add it to the program. You should consult
with your course advisor about what would be appropriate and how to
do it. Grading will be based in part on creativity, ambition, and
degree of consultation. You will probably need to extend your file
format to accommodate the new features.
For example, you could add new options to control the appearance of
strings. The DrawTextItem class, which is used to
represent the strings that are drawn in the picture, has a variety
of properties that can be applied to the strings. Some examples can
be found, commented out, in the doMousePressed() method in the
DrawTextPanel class. Another possibility would be to allow
the user to drag text items around on the screen, after they have
been placed. Or, you could add the ability to create a random text
collage using a bunch of strings selected at random from a text
file specified by the user.
+++++++++++++++++++++++++++++++++++++++++++++++
Please find link below to view DirectoryList.java, DrawTextItem.java, DrawTextPanel.java, SimpleFileChooser.java, TextCollage
https://drive.google.com/drive/folders/1oDWZFjme09ZOtdN3Lxkz2eAvYMEdKMlZ?usp=sharing
/**
* Modified File DrawTextPanel.java
*/
package textcollage;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
/**
* A panel that contains a large drawing area where strings
* can be drawn. The strings are represented by objects of
* type DrawTextItem. An input box under the panel allows
* the user to specify what string will be drawn when the
* user clicks on the drawing area.
*/
public class DrawTextPanel extends JPanel {
// As it now stands, this class can only show one
string at at
// a time! The data for that string is in the
DrawTextItem object
// named theString. (If it's null, nothing is shown.
This
// variable should be replaced by a variable of
type
// ArrayList<DrawStringItem> that can store
multiple items.
private ArrayList<DrawTextItem> theString = new ArrayList<DrawTextItem>(); // change to an ArrayList<DrawTextItem> !
private Color currentTextColor = Color.BLACK; // Color
applied to new strings.
private Canvas canvas; // the drawing area.
private JTextField input; // where the user inputs the
string that will be added to the canvas
private SimpleFileChooser fileChooser; // for letting
the user select files
private JMenuBar menuBar; // a menu bar with command
that affect this panel
private MenuHandler menuHandler; // a listener that
responds whenever the user selects a menu command
private JMenuItem undoMenuItem; // the "Remove Item"
command from the edit menu
/**
* An object of type Canvas is used for the drawing
area.
* The canvas simply displays all the DrawTextItems
that
* are stored in the ArrayList, strings.
*/
private class Canvas extends JPanel {
Canvas() {
setPreferredSize( new Dimension(800,600) );
setBackground(Color.LIGHT_GRAY);
setFont( new
Font( "Serif", Font.BOLD, 24 ));
}
protected void
paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (theString !=
null) {
for (DrawTextItem thisString: theString) {
thisString.draw(g);
}
}
}
}
/**
* An object of type MenuHandler is registered as the
ActionListener
* for all the commands in the menu bar. The
MenuHandler object
* simply calls doMenuCommand() when the user selects a
command
* from the menu.
*/
private class MenuHandler implements ActionListener
{
public void
actionPerformed(ActionEvent evt) {
doMenuCommand(
evt.getActionCommand());
}
}
/**
* Creates a DrawTextPanel. The panel has a large
drawing area and
* a text input box where the user can specify a
string. When the
* user clicks the drawing area, the string is added to
the drawing
* area at the point where the user clicked.
*/
public DrawTextPanel() {
fileChooser = new
SimpleFileChooser();
undoMenuItem = new
JMenuItem("Remove Item");
undoMenuItem.setEnabled(false);
menuHandler = new
MenuHandler();
setLayout(new
BorderLayout(3,3));
setBackground(Color.BLACK);
setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
canvas = new Canvas();
add(canvas,
BorderLayout.CENTER);
JPanel bottom = new JPanel();
bottom.add(new JLabel("Text to add:
"));
input = new JTextField("Hello
World!", 40);
bottom.add(input);
add(bottom,
BorderLayout.SOUTH);
canvas.addMouseListener( new
MouseAdapter() {
public void
mousePressed(MouseEvent e) {
doMousePress( e );
}
} );
}
/**
* This method is called when the user clicks the
drawing area.
* A new string is added to the drawing area. The
center of
* the string is at the point where the user
clicked.
* @param e the mouse event that was generated when the
user clicked
*/
public void doMousePress( MouseEvent e ) {
String text =
input.getText().trim();
if (text.length() == 0) {
input.setText("Hello World!");
text = "Hello
World!";
}
DrawTextItem s = new DrawTextItem(
text, e.getX(), e.getY() );
s.setTextColor(currentTextColor);
// Default is null, meaning default color of the canvas
(black).
// SOME OTHER
OPTIONS THAT CAN BE APPLIED TO TEXT ITEMS:
//
s.setFont( new Font( "Serif", Font.ITALIC + Font.BOLD, 12 )); //
Default is null, meaning font of canvas.
//
s.setMagnification(3); // Default is 1, meaning no
magnification.
//
s.setBorder(true); // Default is false, meaning don't draw a
border.
//
s.setRotationAngle(25); // Default is 0, meaning no rotation.
//
s.setTextTransparency(0.3); // Default is 0, meaning text is not at
all transparent.
//
s.setBackground(Color.BLUE); // Default is null, meaning don't draw
a background area.
//
s.setBackgroundTransparency(0.7); // Default is 0, meaning
background is not transparent.
theString.add(s); // Set this
string as the ONLY string to be drawn on the canvas!
undoMenuItem.setEnabled(true);
canvas.repaint();
}
/**
* Returns a menu bar containing commands that affect
this panel. The menu
* bar is meant to appear in the same window that
contains this panel.
*/
public JMenuBar getMenuBar() {
if (menuBar == null) {
menuBar = new
JMenuBar();
String
commandKey; // for making keyboard accelerators for menu
commands
if
(System.getProperty("mrj.version") == null)
commandKey = "control "; // command key for
non-Mac OS
else
commandKey = "meta "; // command key for Mac
OS
JMenu
fileMenu = new JMenu("File");
menuBar.add(fileMenu);
JMenuItem
saveItem = new JMenuItem("Save...");
saveItem.setAccelerator(KeyStroke.getKeyStroke(commandKey +
"N"));
saveItem.addActionListener(menuHandler);
fileMenu.add(saveItem);
JMenuItem
openItem = new JMenuItem("Open...");
openItem.setAccelerator(KeyStroke.getKeyStroke(commandKey +
"O"));
openItem.addActionListener(menuHandler);
fileMenu.add(openItem);
fileMenu.addSeparator();
JMenuItem
saveImageItem = new JMenuItem("Save Image...");
saveImageItem.addActionListener(menuHandler);
fileMenu.add(saveImageItem);
JMenu
editMenu = new JMenu("Edit");
menuBar.add(editMenu);
undoMenuItem.addActionListener(menuHandler); // undoItem was
created in the constructor
undoMenuItem.setAccelerator(KeyStroke.getKeyStroke(commandKey +
"Z"));
editMenu.add(undoMenuItem);
editMenu.addSeparator();
JMenuItem
clearItem = new JMenuItem("Clear");
clearItem.addActionListener(menuHandler);
editMenu.add(clearItem);
JMenu
optionsMenu = new JMenu("Options");
menuBar.add(optionsMenu);
JMenuItem
colorItem = new JMenuItem("Set Text Color...");
colorItem.setAccelerator(KeyStroke.getKeyStroke(commandKey +
"T"));
colorItem.addActionListener(menuHandler);
optionsMenu.add(colorItem);
JMenuItem
bgColorItem = new JMenuItem("Set Background Color...");
bgColorItem.addActionListener(menuHandler);
optionsMenu.add(bgColorItem);
}
return menuBar;
}
/**
* Carry out one of the commands from the menu
bar.
* @param command the text of the menu command.
*/
private void doMenuCommand(String command) {
if (command.equals("Save...")) { //
save all the string info to a file
//JOptionPane.showMessageDialog(this, "Sorry, the Save command is
not implemented.");
File textFile =
fileChooser.getOutputFile(this, "Select Text File Name",
"text.txt");
if (textFile ==
null)
return;
try {
BufferedWriter bw = new BufferedWriter(new
FileWriter(textFile));
// write bg color
bw.write(canvas.getHeight() + "~"+
canvas.getWidth()+"~"+canvas.getBackground().getRGB());
for (DrawTextItem dti : theString) {
bw.write(System.lineSeparator());
bw.write(dti.getString()+"~"+dti.getX()+"~"+dti.getY()+"~"+dti.getTextColor().getRGB()+"~"+dti.getRotationAngle());
}
bw.close();
}
catch (Exception
e) {
JOptionPane.showMessageDialog(this,
"Sorry, an
error occurred while trying to save the image details:\n" +
e);
}
}
else if (command.equals("Open..."))
{ // read a previously saved file, and reconstruct the list of
strings
//JOptionPane.showMessageDialog(this, "Sorry, the Open command is
not implemented.");
File textFile =
fileChooser.getInputFile(this, "Select Text File Name");
if (textFile ==
null)
return;
try {
Scanner sc = new Scanner(textFile);
String meta = sc.nextLine();
canvas.setSize(Integer.parseInt(meta.split("~")[1]),
Integer.parseInt(meta.split("~")[0]));
canvas.setBackground(new
Color(Integer.parseInt(meta.split("~")[2])));
theString = new
ArrayList<DrawTextItem>();
while(sc.hasNextLine()) {
String element =
sc.nextLine();
DrawTextItem dti = new
DrawTextItem(element.split("~")[0]);
dti.setX(Integer.parseInt(element.split("~")[1]));
dti.setY(Integer.parseInt(element.split("~")[2]));
dti.setTextColor(new
Color(Integer.parseInt(element.split("~")[3])));
dti.setRotationAngle(Double.parseDouble(element.split("~")[4]));
theString.add(dti);
}
//canvas.repaint();
sc.close();
}
catch (Exception
e) {
JOptionPane.showMessageDialog(this,
"Sorry, an
error occurred while trying to save the image details:\n" +
e);
}
canvas.repaint(); // (you'll need this to make the new list of
strings take effect)
}
else if (command.equals("Clear")) {
// remove all strings
theString = new
ArrayList<DrawTextItem>(); // Remove the ONLY
string from the canvas.
undoMenuItem.setEnabled(false);
canvas.repaint();
}
else if (command.equals("Remove
Item")) { // remove the most recently added string
theString.remove(theString.size()-1); // Remove the
ONLY string from the canvas.
if
(theString.size()==0) {
undoMenuItem.setEnabled(false);
}
canvas.repaint();
}
else if (command.equals("Set Text
Color...")) {
Color c =
JColorChooser.showDialog(this, "Select Text Color",
currentTextColor);
if (c !=
null)
currentTextColor = c;
}
else if (command.equals("Set
Background Color...")) {
Color c =
JColorChooser.showDialog(this, "Select Background Color",
canvas.getBackground());
if (c != null)
{
canvas.setBackground(c);
canvas.repaint();
}
}
else if (command.equals("Save
Image...")) { // save a PNG image of the drawing area
File imageFile =
fileChooser.getOutputFile(this, "Select Image File Name",
"textimage.png");
if (imageFile ==
null)
return;
try {
// Because the image is not available, I will
make a new BufferedImage and
// draw the same data to the BufferedImage as is
shown in the panel.
// A BufferedImage is an image that is stored in
memory, not on the screen.
// There is a convenient method for writing a
BufferedImage to a file.
BufferedImage image = new
BufferedImage(canvas.getWidth(),canvas.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setFont(canvas.getFont());
canvas.paintComponent(g); // draws the canvas
onto the BufferedImage, not the screen!
boolean ok = ImageIO.write(image, "PNG",
imageFile); // write to the file
if (ok == false)
throw new Exception("PNG
format not supported (this shouldn't happen!).");
}
catch (Exception
e) {
JOptionPane.showMessageDialog(this,
"Sorry, an
error occurred while trying to save the image:\n" + e);
}
}
}
}
Lab 10: ArrayLists and Files in a GUI Application For this lab, you will work on...
could you please help me with this problem, also I need a little text so I can understand how you solved the problem? import java.io.File; import java.util.Scanner; /** * This program lists the files in a directory specified by * the user. The user is asked to type in a directory name. * If the name entered by the user is not a directory, a * message is printed and the program ends. */ public class DirectoryList { public static...
It is a C++ program by using inheritance and vectors My professor said that all the files should be separate. like File.cpp, File.h, Text.cpp,Text.h,Main.cpp I already have these files File.cpp #include "File.h" // Constructor of File that takes File name and type as arguments File::File(string type, string name) { this->type = type; this->name = name; } //returns the type. string File::getType() { return type; } //returns the name of file. string File::getName() { return name; } File.h #ifndef __FILE_H__ #define...
Reading and Writing Complete Files in C: The first part of the lab is to write a program to read the complete contents of a file to a string. This code will be used in subsequent coding problems. You will need 3 functions: main(), read_file() and write_file(). The main function contains the driver code. The read_file() function reads the complete contents of a file to a string. The write_file() writes the complete contents of a string to a file. The...
I've been assigned to create a new Java application called "CheckString" (without the quotation marks) according to the following guidelines. ** Each method below, including main, should handle (catch) any Exceptions that are thrown. ** ** If an Exception is thrown and caught, print the Exception's message to the command line. ** Write a complete Java method called checkWord that takes a String parameter called word, returns nothing, and is declared to throw an Exception of type Exception. In the...
In this lab you will write a spell check program. The program has two input files: one is the dictionary (a list of valid words) and the other is the document to be spellchecked. The program will read in the words for the dictionary, then will read the document and check whether each word is found in the dictionary. If not, the user will be prompted to leave the word as is or type in a replacement word and add...
Java: student directory GUI You need to implement three classes: Person Student StudentDirectory StudentMain Start by implementing Person and Student classes. Once you are sure you can serialize and deserialize and ArrayList of Students to and from a file, move on to building the GUI application. Person: The Person class should implement serializable interface. It contains the following: Person's first name (String) Person's last name (String) Person's id number Person's date of birth (Date) public String toString(): This method method...
This assignment uses functions, files, and strings. Enough flexibility is provided for you to apply your knowledge of basic C++ programing to develop your solution. Develop a functional flowchart and then write a C++ program to solve the following problem. 1. Create a text file named file1.txt and write your brand of car (like Honda, Toyota, etc) in the file. You will be reading the name of the file from the keyboard as a string, using the string class. Your...
Dictionary.java DictionaryInterface.java Spell.java SpellCheck.java In this lab you will write a spell check program. The program has two input files: one is the dictionary (a list of valid words) and the other is the input file to be spell checked. The program will read in the words for the dictionary, then will read the input file and check whether each word is found in the dictionary. If not, the user will be prompted to leave the word as is, add...
In Java. Write a GUI contact list application. The program should allow you to input names and phone numbers. You should also be able to input a name and have it display the previously entered phone number. The GUI should look something like the following, although you are welcome to format it in any way that works. This should be a GUI application with a JFrame. The program should contain two arrays of Strings. One array will contain a list...
Need help on following Java GUI problem: Write a program that lets a user display and modify pictures. Create a window. Add four buttons so that clicking a particular button will shift the image by a small amount in the north, south, east or west direction inside the window. Add a menu bar with two menus: File and Image. The File menu should contain an Open menu item that the user can select to display JPEG and PNG files from...