44import java .awt .event .ActionListener ;
55import java .io .File ;
66
7- import javax .swing .JButton ;
8- import javax .swing .JFrame ;
9- import javax .swing .JLabel ;
10- import javax .swing .JOptionPane ;
11- import javax .swing .JPanel ;
12-
13- import prog .huffman .HuffmanCompressor ;
14- import prog .huffman .HuffmanDecompressor ;
15- import prog .lzw .LzwCompressor ;
16- import prog .lzw .LzwDecompressor ;
17- import prog .util .Constants ;
18-
19- public class Main extends JFrame implements ActionListener {
20- // Definition of global values and items that are part of the GUI.
21-
22- static public File openedFile , outputFile ;
23- static long originalSize , compressedSize ;
24- static JLabel originalSizeLabel , compressedSizeLabel , originalSizeValue , compressedSizeValue ;
25- static JPanel buttonPanel , titlePanel , scorePanel ;
26- static JButton huffmanCompressButton , huffmanDecompressButton , lzwCompressButton , lzwDecompressButton , exitButton ;
7+ import javax .swing .*;
278
9+ import org .slf4j .Logger ;
10+ import org .slf4j .LoggerFactory ;
11+
12+ import prog .handler .CompressionHandler ;
13+ import prog .handler .DecompressionHandler ;
14+ import prog .handler .FileOperationHandler ;
15+ import prog .ui .FileCompressorUI ;
16+ import prog .ui .MainWindow ;
17+
18+ /**
19+ * Main application class for the File Compressor.
20+ * Coordinates between UI components and business logic handlers.
21+ */
22+ public class Main implements ActionListener {
23+ private static final Logger logger = LoggerFactory .getLogger (Main .class );
24+
25+ // Handlers
26+ private final FileOperationHandler fileHandler ;
27+ private final CompressionHandler compressionHandler ;
28+ private final DecompressionHandler decompressionHandler ;
29+
30+ // UI Components
31+ private final FileCompressorUI ui ;
32+ private JTextField filePathField ;
33+ private JLabel originalSizeValue ;
34+ private JLabel compressedSizeValue ;
35+ private JLabel statusLabel ;
36+ private JButton huffmanCompressButton ;
37+ private JButton huffmanDecompressButton ;
38+ private JButton lzwCompressButton ;
39+ private JButton lzwDecompressButton ;
40+ private JButton exitButton ;
41+
42+ public Main () {
43+ this .ui = new FileCompressorUI ();
44+ this .fileHandler = new FileOperationHandler ();
45+ this .compressionHandler = new CompressionHandler ();
46+ this .decompressionHandler = new DecompressionHandler ();
47+ }
48+
49+ /**
50+ * Creates the content pane and initializes UI components
51+ */
2852 public JPanel createContentPane () {
29- return MainPanel .createContentPane (this );
53+ JPanel contentPane = ui .createContentPane (this , this ::handleBrowse );
54+
55+ // Get references to UI components
56+ filePathField = ui .getFilePathField ();
57+ originalSizeValue = ui .getOriginalSizeValue ();
58+ compressedSizeValue = ui .getCompressedSizeValue ();
59+ statusLabel = ui .getStatusLabel ();
60+ huffmanCompressButton = ui .getHuffmanCompressButton ();
61+ huffmanDecompressButton = ui .getHuffmanDecompressButton ();
62+ lzwCompressButton = ui .getLzwCompressButton ();
63+ lzwDecompressButton = ui .getLzwDecompressButton ();
64+ exitButton = ui .getExitButton ();
65+
66+ return contentPane ;
67+ }
68+
69+ /**
70+ * Handles the browse button action to open file chooser
71+ */
72+ private void handleBrowse (ActionEvent e ) {
73+ File selectedFile = fileHandler .browseForFile ();
74+ if (selectedFile != null ) {
75+ filePathField .setText (selectedFile .getAbsolutePath ());
76+ originalSizeValue .setText (fileHandler .formatFileSize (selectedFile .length ()));
77+ compressedSizeValue .setText ("—" );
78+ statusLabel .setText ("File selected: " + selectedFile .getName ());
79+ }
80+ }
81+
82+ /**
83+ * Handles the File > Open menu action
84+ */
85+ private void handleFileOpen () {
86+ handleBrowse (null );
87+ }
88+
89+ /**
90+ * Validates that a file is selected before performing operations
91+ */
92+ private boolean validateFileSelected () {
93+ if (!fileHandler .isFileSelected ()) {
94+ fileHandler .showNoFileSelectedWarning ();
95+ statusLabel .setText ("⚠️ No file selected" );
96+ return false ;
97+ }
98+ return true ;
3099 }
31100
32101 private void handleHuffmanCompression () {
33- HuffmanCompressor .beginHuffmanCompression (openedFile .getPath ());
34- showCompressionCompleteDialog ("Zipping" );
35- updateFileStats (Constants .HUFFMAN_FILE_EXTENSION );
102+ if (!validateFileSelected ()) return ;
103+
104+ statusLabel .setText ("🗜️ Compressing with Huffman..." );
105+ File outputFile = compressionHandler .compressWithHuffman (fileHandler .getSelectedFile ());
106+
107+ if (outputFile != null ) {
108+ fileHandler .setOutputFile (outputFile );
109+ updateCompressionStats ();
110+ statusLabel .setText ("✅ Compression complete!" );
111+ } else {
112+ statusLabel .setText ("❌ Compression failed" );
113+ }
36114 }
37115
38116 private void handleHuffmanDecompression () {
39- HuffmanDecompressor .beginHuffmanDecompression (openedFile .getPath ());
40- showCompressionCompleteDialog ("UnZipping" );
41- updateDecompressionStats ();
117+ if (!validateFileSelected ()) return ;
118+
119+ statusLabel .setText ("📂 Decompressing Huffman file..." );
120+ File outputFile = decompressionHandler .decompressHuffman (fileHandler .getSelectedFile ());
121+
122+ if (outputFile != null ) {
123+ fileHandler .setOutputFile (outputFile );
124+ updateDecompressionStats ();
125+ statusLabel .setText ("✅ Decompression complete!" );
126+ } else {
127+ statusLabel .setText ("❌ Decompression failed" );
128+ }
42129 }
43130
44131 private void handleLZWCompression () {
45- LzwCompressor .beginLzwCompression (openedFile .getPath ());
46- showCompressionCompleteDialog ("Zipping" );
47- updateFileStats (Constants .LZW_FILE_EXTENSION );
132+ if (!validateFileSelected ()) return ;
133+
134+ statusLabel .setText ("🗜️ Compressing with LZW..." );
135+ File outputFile = compressionHandler .compressWithLZW (fileHandler .getSelectedFile ());
136+
137+ if (outputFile != null ) {
138+ fileHandler .setOutputFile (outputFile );
139+ updateCompressionStats ();
140+ statusLabel .setText ("✅ Compression complete!" );
141+ } else {
142+ statusLabel .setText ("❌ Compression failed" );
143+ }
48144 }
49145
50146 private void handleLZWDecompression () {
51- LzwDecompressor . beginLzwDecompression ( openedFile . getPath ());
52- showCompressionCompleteDialog ( "UnZipping" );
53- updateDecompressionStats ( );
54- }
147+ if (! validateFileSelected ()) return ;
148+
149+ statusLabel . setText ( "📂 Decompressing LZW file..." );
150+ File outputFile = decompressionHandler . decompressLZW ( fileHandler . getSelectedFile ());
55151
56- private void showCompressionCompleteDialog (String operation ) {
57- JOptionPane .showMessageDialog (null ,
58- "..........................." + operation + " Finished.........................." ,
59- "Status" , JOptionPane .PLAIN_MESSAGE );
152+ if (outputFile != null ) {
153+ fileHandler .setOutputFile (outputFile );
154+ updateDecompressionStats ();
155+ statusLabel .setText ("✅ Decompression complete!" );
156+ } else {
157+ statusLabel .setText ("❌ Decompression failed" );
158+ }
60159 }
61160
62- private void updateFileStats (String extension ) {
63- originalSizeValue .setText (openedFile .length () + "Bytes" );
64- outputFile = new File (openedFile .getPath () + extension );
65- compressedSize = outputFile .length ();
66- compressedSizeValue .setText (compressedSize + "Bytes" );
161+ private void updateCompressionStats () {
162+ File inputFile = fileHandler .getSelectedFile ();
163+ File outputFile = fileHandler .getOutputFile ();
164+
165+ originalSizeValue .setText (fileHandler .formatFileSize (inputFile .length ()));
166+ compressedSizeValue .setText (fileHandler .formatFileSize (outputFile .length ()));
167+
168+ // Calculate and show compression ratio
169+ double ratio = compressionHandler .calculateCompressionRatio (
170+ inputFile .length (), outputFile .length ());
171+
172+ if (ratio > 0 ) {
173+ statusLabel .setText (String .format ("✅ Compression complete! Saved %.1f%%" , ratio ));
174+ }
67175 }
68176
69177 private void updateDecompressionStats () {
70- originalSizeValue .setText (openedFile .length () + "Bytes" );
71- String s = openedFile .getPath ();
72- s = s .substring (0 , s .length () - 6 );
73- outputFile = new File (s );
74- compressedSize = outputFile .length ();
75- compressedSizeValue .setText (compressedSize + "Bytes" );
178+ File inputFile = fileHandler .getSelectedFile ();
179+ File outputFile = fileHandler .getOutputFile ();
180+
181+ originalSizeValue .setText (fileHandler .formatFileSize (inputFile .length ()));
182+ compressedSizeValue .setText (fileHandler .formatFileSize (outputFile .length ()));
76183 }
77184
185+ @ Override
78186 public void actionPerformed (ActionEvent e ) {
79187 if (e .getSource () == huffmanCompressButton ) {
80188 handleHuffmanCompression ();
@@ -89,7 +197,30 @@ public void actionPerformed(ActionEvent e) {
89197 }
90198 }
91199
200+ // Getter methods for testing
201+ public JTextField getFilePathField () { return filePathField ; }
202+ public JLabel getOriginalSizeValue () { return originalSizeValue ; }
203+ public JLabel getCompressedSizeValue () { return compressedSizeValue ; }
204+ public JLabel getStatusLabel () { return statusLabel ; }
205+ public JButton getHuffmanCompressButton () { return huffmanCompressButton ; }
206+ public JButton getHuffmanDecompressButton () { return huffmanDecompressButton ; }
207+ public JButton getLzwCompressButton () { return lzwCompressButton ; }
208+ public JButton getLzwDecompressButton () { return lzwDecompressButton ; }
209+ public JButton getExitButton () { return exitButton ; }
210+ public File getOpenedFile () { return fileHandler .getSelectedFile (); }
211+
212+ /**
213+ * Main entry point for the application
214+ */
92215 public static void main (String [] args ) {
93- MainFrame .init ();
216+ logger .info ("Starting File Compressor application" );
217+ logger .debug ("Java version: {}" , System .getProperty ("java.version" ));
218+ logger .debug ("OS: {} {}" , System .getProperty ("os.name" ), System .getProperty ("os.version" ));
219+
220+ Main app = new Main ();
221+ JPanel contentPane = app .createContentPane ();
222+ MainWindow .init (contentPane , e -> app .handleFileOpen ());
223+
224+ logger .info ("Application UI initialized successfully" );
94225 }
95226}
0 commit comments