For this assignment, you will be furnished with the skeleton structure of a Swin
ID: 3686493 • Letter: F
Question
For this assignment, you will be furnished with the skeleton structure of a Swing GUI application for displaying letter occurrence histograms for the sentences in a selected text file. The skeleton code is in two files thatyou can download from the links in the NetBeans Project Setup section below. These files contain empty methods for four methods, which you will need to develop. It will be your task to develop the event handlers and histogram display methods, plus any support utility methods you wish to make the program operate as described below.
Program Operation
When the program is launched from the command line, the following GUI will appear:
When the "Load File" button is pressed, a file chooser should appear. You must develop the code to implement this feature.
When the "Show Histo for Sentence" button is pressed, or when the cursor is in the textfield and the Enter key is pressed, the program should attempt to parse an integer from the text field. If there is no value or the value cannot be parsed as an integer, the program should present the JOptionPane message shown here. You must develop the code to implement this feature.
If the value in the text field can be parsed as an integer, but the integer value is less than zero or greater than the greatest sentence index, the program presents the JOptionPane message shown here. This is functionality that is already provided by the skeleton code, so you do not need to implement this feature.
But if the value can be parsed as an integer within range, then the program should compute the letter occurrence histogram for the sentence and display it graphically in the right pane, as shown here. You must develop the code to implement this feature.
The histogram display methods should be developed so that when the GUI window is resized, the histogram display automatically refreshes and resizes to fit within the available space, as shown below. You must develop the code to implement this feature.
Input File Format
The input file format is the same as for Program 3. For details please see that assignment. The sample data file for the output shown above is:
Specific Requirements
1. Any existing histogram should be cleared before displaying a subsequent sentence histogram, so that the display should never show two histograms one on top of the other, nor should it show histogram bars that stack one on top of the other.
2. Your name must appear in the title bar of the GUI frame, as shown above. This should be done in the Histogram class constructor.
3. When the "Load File" button is pressed:
(a) a file chooser must appear;
(b) the "Cancel" button on the chooser must be operational and must return the user to the main GUI.
(c) when the "Open" button is pressed on the file chooser dialog, the dialog must close and the input sentences must be numbered and shown in the "sourceArea" text area, separated by empty lines.
(d) the "showButton" and "numField" variables must be enabled, and any text in the numField must be cleared so that the text field appears empty.
(e) if there is a histogram in the right display panel, it should also be cleared.
4. When the "Show Histo for Sentence" button is pressed:
(a) if the value in the idField cannot be parsed as an integer, the program should display a JOptionPane message dialog stating, "Text field is not an integer".
(b) if the value in the idField can be parsed as an integer within range, the program should (i) compute the letter occurrence histogram for the sentence that has that integer value as an index, and (ii) display the histogram graphically on the "outPanel" as shown above. Please note that the histogram should fill the available area in the right-hand panel of the GUI with 10% margins on all sides, as shown here:
NetBeans Project Setup
These instructions set up the skeleton program in your NetBeans. It should run but do nothing other than show the initial GUI. You must extend the skeleton code as described above to achieve the required functionality.
1. Create a Java application project called ”Histogram" in NetBeans. Edit the project’s packaging properties to include Java source (.java) files in the JAR.
2. Create a Java package called ”histogram" in this project if not already created for you by NetBeans.
3. Create a regular Java class file (not a Swing GUI form) named ”HistogramPanel.java" in this package.
6. Edit your project’s run properties to use histogram.Histogram as the main class
Programming Tips
1. Use the BarChart and BarChartPanel classes from lecture as a starting point. These classes create and display fixed size histograms, so you will need to extend the logic to handle resizing of the display window.
2. In your HistogramPanel class, scale the heights and widths of lines and rectangles using this.getHeight() and this.getWidth(). Once you have these values, it is relatively simple algebra to scale the lines and rectangle.
3. Don't try to do everything inside the drawLines() and drawHisto() methods. It will be easier to debug if you put common code and self-contained functionality in separate utility methods that are called from these methods. See the Bar Chart code for examples of how to do this.
Explanation / Answer
Histogram.java
import java.io.File;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
public class Histogram extends javax.swing.JFrame {
/**
* Creates new form HistoFrame
*/
public Histogram() {
initComponents();
this.setTitle("Sentence Histograms by Jonathan Lundstrom");
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
topPanel = new javax.swing.JPanel();
loadButton = new javax.swing.JButton();
showButton = new javax.swing.JButton();
numField = new javax.swing.JTextField();
mainPanel = new javax.swing.JPanel();
jSplitPane1 = new javax.swing.JSplitPane();
jScrollPane1 = new javax.swing.JScrollPane();
sourceArea = new javax.swing.JTextArea();
outPanel = new histogram.HistogramPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
topPanel.setBackground(new java.awt.Color(230, 240, 255));
topPanel.setPreferredSize(new java.awt.Dimension(686, 40));
loadButton.setText("Load File");
loadButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
loadButtonActionPerformed(evt);
}
});
topPanel.add(loadButton);
showButton.setText("Show Histo for Sentence");
showButton.setEnabled(false);
showButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
showButtonActionPerformed(evt);
}
});
topPanel.add(showButton);
numField.setColumns(3);
numField.setEnabled(false);
numField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
numFieldActionPerformed(evt);
}
});
topPanel.add(numField);
getContentPane().add(topPanel, java.awt.BorderLayout.PAGE_START);
mainPanel.setLayout(new javax.swing.BoxLayout(mainPanel, javax.swing.BoxLayout.X_AXIS));
jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
sourceArea.setColumns(20);
sourceArea.setLineWrap(true);
sourceArea.setRows(5);
jScrollPane1.setViewportView(sourceArea);
jSplitPane1.setLeftComponent(jScrollPane1);
outPanel.setBackground(new java.awt.Color(230, 230, 230));
outPanel.addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(java.awt.event.ComponentEvent evt) {
outPanelComponentResized(evt);
}
});
javax.swing.GroupLayout outPanelLayout = new javax.swing.GroupLayout(outPanel);
outPanel.setLayout(outPanelLayout);
outPanelLayout.setHorizontalGroup(
outPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 128, Short.MAX_VALUE)
);
outPanelLayout.setVerticalGroup(
outPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 256, Short.MAX_VALUE)
);
jSplitPane1.setRightComponent(outPanel);
mainPanel.add(jSplitPane1);
getContentPane().add(mainPanel, java.awt.BorderLayout.CENTER);
pack();
}// </editor-fold>//GEN-END:initComponents
private void loadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadButtonActionPerformed
//Handle open button action.
sourceArea.setText("");
if (evt.getSource() == loadButton) {
JFileChooser fDialog = new JFileChooser();
int returnVal = fDialog.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fDialog.getSelectedFile();
showButton.setEnabled(true);
numField.setEnabled(true);
sourceArea.setText(outPanel.readFile(file));
} else {
showButton.setEnabled(false);
numField.setEnabled(false);
}
}
}//GEN-LAST:event_loadButtonActionPerformed
private void showButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showButtonActionPerformed
String numIn = numField.getText();
int i;
try
{
i = Integer.parseInt(numIn);
outPanel.showHisto(i, true);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this, "Text field is not an integer");
}
}//GEN-LAST:event_showButtonActionPerformed
private void numFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_numFieldActionPerformed
showButtonActionPerformed( evt );
}//GEN-LAST:event_numFieldActionPerformed
private void outPanelComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_outPanelComponentResized
outPanel.showHisto();
}//GEN-LAST:event_outPanelComponentResized
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Histogram.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Histogram().setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JButton loadButton;
private javax.swing.JPanel mainPanel;
private javax.swing.JTextField numField;
private histogram.HistogramPanel outPanel;
private javax.swing.JButton showButton;
private javax.swing.JTextArea sourceArea;
private javax.swing.JPanel topPanel;
// End of variables declaration//GEN-END:variables
}
HistogramPanel.java
import java.awt.Color;
import java.awt.Graphics;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class HistogramPanel extends JPanel {
private List<String> sents;
private int snum;
public String readFile( File file ) {
sents = new ArrayList();
snum = -1;
clearDisplay( this.getGraphics() );
StringBuilder sb = new StringBuilder();
try {
Scanner scanner = new Scanner( new FileInputStream(file));
while( scanner.hasNextLine() ) {
sents.add( scanner.nextLine() );
}
for( int i = 0; i < sents.size(); i++ ) {
sb.append(i + " : " + sents.get( i ) + " ");
}
} catch (FileNotFoundException ex) {
Logger.getLogger(HistogramPanel.class.getName()).log(Level.SEVERE, null, ex);
}
return sb.toString().trim();
}
@Override
public void paintComponent( Graphics gc ) {
super.paintComponent( gc );
if( sents != null && snum >= 0 && snum < sents.size() ) {
showHisto( snum, true );
}
}
public void showHisto() {
this.setBackground( Color.white );
showHisto( snum, false );
}
public void showHisto( int n, boolean b ) {
if( sents != null && n >= 0 && n < sents.size() ) {
snum = n;
Graphics gc = this.getGraphics();
clearDisplay( gc );
drawLines( gc );
drawHisto( gc );
}
else if( b && sents != null ) {
JOptionPane.showMessageDialog(this, "Sentence index out of range");
}
}
private void clearDisplay( Graphics gc ) {
gc.setColor( Color.WHITE );
gc.fillRect(0,0,this.getWidth(),this.getHeight());
}
private void drawLines( Graphics gc ) {
int x = this.getWidth()/10, y = this.getHeight()/10;
gc.setColor(Color.red);
gc.drawLine(x, y, x, y*9);
gc.drawLine(x, y*9, x*9, y*9);
}
private void drawHisto( Graphics gc ) {
int x = this.getWidth()/10, y = this.getHeight()/10, max = 0, c;
int counts[] = new int[26];
String line = sents.get(snum).toLowerCase();
for (int i = 0; i < line.length(); i++) {
c = line.charAt(i) - 'a';
if (c >= 0 && c < 26) {
counts[c]++;
max = Math.max(max,counts[c]);
}
}
gc.setColor(Color.blue);
int width = x*8/26;
for (int i = 0; i < counts.length; i++) {
int height = y*8*counts[i]/max;
gc.drawRect(x + i*width, y*9 - height, width, height);
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.