Files
cvbuilder_0/src/main/java/cvbuilder/view/MainViewer.java
T

560 lines
21 KiB
Java

package cvbuilder.view;
import cvbuilder.controller.CsvExportSettings;
import cvbuilder.model.User;
import cvbuilder.model.UserGroup;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
public class MainViewer {
private final UserGroup userGroup;
public MainViewer() {
userGroup = UserGroup.getInstance();
// Create the main frame
JFrame viewer = new JFrame("CV Builder");
viewer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
viewer.setSize(800, 500);
// Create menu bar
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
viewer.setJMenuBar(menuBar);
// Set up the Open and Save menu items
setupMenu(viewer);
// Add content to the frame
populateMainPanel(viewer);
// Make the frame visible after all content is added
viewer.setVisible(true);
}
private void populateMainPanel(JFrame viewer) {
JTabbedPane outer = new JTabbedPane();
JTabbedPane userT = new JTabbedPane();
JTabbedPane contactT = new JTabbedPane();
// User tab
JPanel title = new JPanel();
title.setName("title");
JPanel name = new JPanel();
name.setName("name");
JPanel email = new JPanel();
email.setName("email");
populatePanel(title);
populatePanel(name);
populatePanel(email);
userT.addTab("Title", title);
userT.addTab("Name", name);
userT.addTab("Email", email);
outer.addTab("User", userT);
// Contact tab
JPanel phone = new JPanel();
phone.setName("phone");
JPanel address = new JPanel();
address.setName("address");
populatePanel(phone);
populatePanel(address);
contactT.addTab("Phone", phone);
contactT.addTab("Address", address);
outer.addTab("Contact", contactT);
// Create main container with BorderLayout
JPanel mainContainer = new JPanel(new BorderLayout());
mainContainer.add(outer, BorderLayout.CENTER);
// Add footer with navigation buttons
JPanel footer = createFooter(outer);
mainContainer.add(footer, BorderLayout.SOUTH);
viewer.getContentPane().add(mainContainer);
viewer.revalidate();
}
private void populatePanel(JPanel panel) {
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
ButtonGroup group = new ButtonGroup();
String panelName = panel.getName();
// Add "Include in CSV" checkbox at the top - but NOT for name or email panels
if (!panelName.equalsIgnoreCase("name") && !panelName.equalsIgnoreCase("email")) {
JPanel includePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JCheckBox includeCheckbox = new JCheckBox("Include in CSV");
includeCheckbox.setSelected(true); // Default to selected
includePanel.add(includeCheckbox);
// Store selection in the CsvExportSettings
includeCheckbox.addActionListener(e -> {
boolean include = includeCheckbox.isSelected();
System.out.println("Include " + panelName + " in CSV: " + include);
CsvExportSettings.getInstance().setInclude(panelName, include);
});
panel.add(includePanel);
panel.add(Box.createVerticalStrut(5));
panel.add(new JSeparator(JSeparator.HORIZONTAL));
panel.add(Box.createVerticalStrut(10));
} else {
// For name and email, always set them to be included without showing checkbox
CsvExportSettings.getInstance().setInclude(panelName, true);
}
if (userGroup.getUsers().isEmpty()) {
panel.add(new JLabel("No users available"));
return;
}
// Add existing users
for (int i = 0; i < userGroup.getUsers().size(); i++) {
User user = userGroup.getUsers().get(i);
String value = user.getUserAttribute(panelName);
if (value != null && !value.isEmpty()) {
// Create a panel for each entry with radio button and action buttons
JPanel entryPanel = new JPanel();
entryPanel.setLayout(new BoxLayout(entryPanel, BoxLayout.X_AXIS));
// Create radio button
JRadioButton radioButton = new JRadioButton(value);
group.add(radioButton);
entryPanel.add(radioButton);
// Add some spacing
entryPanel.add(Box.createHorizontalStrut(10));
// Create Edit button
JButton editButton = new JButton("Edit");
final int userIndex = i;
editButton.addActionListener(e -> {
String newValue = showDialog("Edit " + panelName, value);
if (newValue != null && !newValue.isEmpty()) {
// Update the user attribute
switch (panelName.toLowerCase()) {
case "title" -> user.setTitle(newValue);
case "name" -> user.setName(newValue);
case "email" -> user.setEmail(newValue);
case "phone" -> user.setPhone(newValue);
case "address" -> user.setAddress(newValue);
}
// Update the radio button label
radioButton.setText(newValue);
}
});
entryPanel.add(editButton);
// Add some spacing
entryPanel.add(Box.createHorizontalStrut(5));
// Create delete button
JButton deleteButton = new JButton("Delete");
deleteButton.addActionListener(e -> {
// Remove the user without confirmation
userGroup.getUsers().remove(userIndex);
// Refresh all panels
JFrame frame = (JFrame) SwingUtilities.getWindowAncestor(panel);
frame.getContentPane().removeAll();
populateMainPanel(frame);
frame.revalidate();
frame.repaint();
});
entryPanel.add(deleteButton);
// Add padding to align elements
entryPanel.add(Box.createHorizontalGlue());
// Add the entry panel to the main panel
panel.add(entryPanel);
}
}
// Add a separator
panel.add(Box.createVerticalStrut(20));
panel.add(new JSeparator(JSeparator.HORIZONTAL));
panel.add(Box.createVerticalStrut(10));
// Add the "Add Row" interface at the bottom
JPanel addRowPanel = new JPanel();
addRowPanel.setLayout(new BoxLayout(addRowPanel, BoxLayout.X_AXIS));
addRowPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 80));
JTextField newValueField = new JTextField(15);
JButton addButton = new JButton("Add Row");
addRowPanel.add(new JLabel("New " + panelName + ": "));
addRowPanel.add(newValueField);
addRowPanel.add(Box.createHorizontalStrut(10));
addRowPanel.add(addButton);
// Add row action
addButton.addActionListener(e -> {
String newValue = newValueField.getText().trim();
if (!newValue.isEmpty()) {
// Create a new user
User newUser = new User();
// Set all attributes to "Unknown" by default
newUser.setName("Unknown");
newUser.setTitle("Unknown");
newUser.setEmail("Unknown");
newUser.setPhone("Unknown");
newUser.setAddress("Unknown");
// Set the specific attribute from the input field
switch (panelName.toLowerCase()) {
case "title" -> newUser.setTitle(newValue);
case "name" -> newUser.setName(newValue);
case "email" -> newUser.setEmail(newValue);
case "phone" -> newUser.setPhone(newValue);
case "address" -> newUser.setAddress(newValue);
}
// Add the new user to the group
userGroup.addUser(newUser);
// Refresh all panels
JFrame frame = (JFrame) SwingUtilities.getWindowAncestor(panel);
frame.getContentPane().removeAll();
populateMainPanel(frame);
frame.revalidate();
frame.repaint();
// Clear the input field
newValueField.setText("");
} else {
JOptionPane.showMessageDialog(panel,
"Please enter a value for the new " + panelName,
"Empty Value", JOptionPane.WARNING_MESSAGE);
}
});
panel.add(addRowPanel);
// Add vertical glue to push all components to the top
panel.add(Box.createVerticalGlue());
}
private String showDialog(String title, String initialValue) {
JTextField textField = new JTextField(initialValue);
JLabel label = new JLabel("Enter new text:");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 1));
panel.add(label);
panel.add(textField);
JOptionPane pane = new JOptionPane(panel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
JDialog dialog = pane.createDialog("Rename Dialogue Box");
dialog.setVisible(true);
// Process the user's choice
Object value = pane.getValue();
if (value instanceof Integer) {
int choice = (Integer) value;
if (choice == JOptionPane.OK_OPTION) {
String newValue = textField.getText().trim();
System.out.println("OK option pressed and set text to: " + newValue + " for tab: " + title);
return newValue;
} else if (choice == JOptionPane.CANCEL_OPTION) {
System.out.println("Cancel option pressed for tab: " + title);
}
}
dialog.dispose();
return null;
}
private JPanel createFooter(JTabbedPane tabbedPane) {
JPanel footer = new JPanel(new BorderLayout());
footer.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JButton prevButton = new JButton("Previous Section");
JButton nextButton = new JButton("Next Section");
// Style the buttons
prevButton.setFocusPainted(false);
nextButton.setFocusPainted(false);
// Add action listeners
prevButton.addActionListener(e -> {
int currentIndex = tabbedPane.getSelectedIndex();
if (currentIndex > 0) {
tabbedPane.setSelectedIndex(currentIndex - 1);
}
});
nextButton.addActionListener(e -> {
int currentIndex = tabbedPane.getSelectedIndex();
if (currentIndex < tabbedPane.getTabCount() - 1) {
tabbedPane.setSelectedIndex(currentIndex + 1);
}
});
// Add buttons to footer
footer.add(prevButton, BorderLayout.WEST);
footer.add(nextButton, BorderLayout.EAST);
return footer;
}
private void setupMenu(JFrame viewer) {
JMenuBar menuBar = viewer.getJMenuBar();
JMenu menu = menuBar.getMenu(0); // Get the existing "Menu" menu
// Create Open menu item
JMenuItem openItem = new JMenuItem("Open");
openItem.addActionListener(e -> openCsvFile(viewer));
// Create Save menu item
JMenuItem saveItem = new JMenuItem("Save");
saveItem.addActionListener(e -> saveCsvFile(viewer));
menu.add(new JSeparator());
menu.add(openItem);
menu.add(saveItem);
}
// Class variable to store the current CSV file path -- added default file data
private String currentCsvFile = "data/cv_repo_0.csv";
private void openCsvFile(JFrame viewer) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("Open CSV File");
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.isDirectory() || f.getName().toLowerCase().endsWith(".csv");
}
public String getDescription() {
return "CSV Files (*.csv)";
}
});
int result = fileChooser.showOpenDialog(viewer);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
loadCsvFile(selectedFile.getAbsolutePath(), viewer);
}
}
private void loadCsvFile(String filePath, JFrame viewer) {
UserGroup userGroup = UserGroup.getInstance();
userGroup.clearUsers(); // Clear existing users
try (BufferedReader r = new BufferedReader(new FileReader(filePath))) {
// Skip the first line (Section,Sub-Section,Variants)
r.readLine();
// Read all lines into memory so we can process by column
String[] lines = r.lines().toArray(String[]::new);
// First pass: determine maximum number of users
int maxUserCount = 0;
for (String line : lines) {
String[] parts = line.split(",");
int userCount = parts.length - 2; // Subtract first two columns
maxUserCount = Math.max(maxUserCount, userCount);
}
// Create all users with default "Unknown" values
for (int i = 0; i < maxUserCount; i++) {
User user = new User();
user.setName("Unknown");
user.setTitle("Unknown");
user.setEmail("Unknown");
user.setPhone("Unknown");
user.setAddress("Unknown");
userGroup.addUser(user);
}
// Second pass: fill in actual values where available
for (String line : lines) {
String[] parts = line.split(",");
if (parts.length < 3) continue;
String sectionType = parts[0] + "," + parts[1];
// Process each user column (starting from column 2, index 2)
for (int colIndex = 2; colIndex < parts.length; colIndex++) {
int userIndex = colIndex - 2; // User index starts from 0
if (userIndex < userGroup.getUsers().size()) {
User user = userGroup.getUsers().get(userIndex);
String value = parts[colIndex].trim();
// Only update if the value is not empty
if (!value.isEmpty()) {
switch (sectionType) {
case "User,Name" -> user.setName(value);
case "User,Title" -> user.setTitle(value);
case "User,Email" -> user.setEmail(value);
case "Contact Information,Phone" -> user.setPhone(value);
case "Contact Information,Address" -> user.setAddress(value);
}
}
}
}
}
// Store the current file path
currentCsvFile = filePath;
// Refresh the UI
viewer.getContentPane().removeAll();
populateMainPanel(viewer);
viewer.revalidate();
viewer.repaint();
System.out.println("Loaded " + maxUserCount + " users from " + filePath);
} catch (IOException e) {
JOptionPane.showMessageDialog(viewer,
"Error loading CSV file: " + e.getMessage(),
"File Error",
JOptionPane.ERROR_MESSAGE);
}
}
private void saveCsvFile(JFrame viewer) {
if (currentCsvFile == null) {
// No file loaded yet, show save dialog
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("Save CSV File");
fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.isDirectory() || f.getName().toLowerCase().endsWith(".csv");
}
public String getDescription() {
return "CSV Files (*.csv)";
}
});
int result = fileChooser.showSaveDialog(viewer);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
String path = selectedFile.getAbsolutePath();
if (!path.toLowerCase().endsWith(".csv")) {
path += ".csv";
}
currentCsvFile = path;
writeToCSV(currentCsvFile);
}
} else {
// Use the existing file path
writeToCSV(currentCsvFile);
}
}
private void writeToCSV(String filePath) {
// First read the existing file to preserve data for sections not included
Map<String, String[]> existingData = new HashMap<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
// Skip the header
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",", 3); // Split into section, subsection, and the rest
if (parts.length >= 2) {
String key = parts[0] + "," + parts[1];
// Store the whole line
existingData.put(key, line.split(","));
}
}
} catch (IOException e) {
// If file doesn't exist or can't be read, we'll create a new one
// No need to handle this exception
}
try (PrintWriter writer = new PrintWriter(new FileWriter(filePath))) {
// Get export settings
CsvExportSettings exportSettings = CsvExportSettings.getInstance();
// Write header
writer.println("Section,Sub-Section,Variants");
// Get all users
UserGroup userGroup = UserGroup.getInstance();
// Build user data strings to append - we'll use these if the section should be included
String[] nameData = new String[userGroup.getUsers().size()];
String[] titleData = new String[userGroup.getUsers().size()];
String[] emailData = new String[userGroup.getUsers().size()];
String[] phoneData = new String[userGroup.getUsers().size()];
String[] addressData = new String[userGroup.getUsers().size()];
for (int i = 0; i < userGroup.getUsers().size(); i++) {
User user = userGroup.getUsers().get(i);
nameData[i] = user.getName();
titleData[i] = user.getTitle();
emailData[i] = user.getEmail();
phoneData[i] = user.getPhone();
addressData[i] = user.getAddress();
}
// Process and write each section based on inclusion settings
// Name - always included
writeSection(writer, existingData, "User,Name", nameData, true);
// Title - conditionally included
writeSection(writer, existingData, "User,Title", titleData, exportSettings.isIncluded("title"));
// Email - always included
writeSection(writer, existingData, "User,Email", emailData, true);
// Phone - conditionally included
writeSection(writer, existingData, "Contact Information,Phone", phoneData, exportSettings.isIncluded("phone"));
// Address - conditionally included
writeSection(writer, existingData, "Contact Information,Address", addressData, exportSettings.isIncluded("address"));
} catch (IOException e) {
JOptionPane.showMessageDialog(null,
"Error saving CSV file: " + e.getMessage(),
"File Error",
JOptionPane.ERROR_MESSAGE);
}
}
private void writeSection(PrintWriter writer, Map<String, String[]> existingData, String section,
String[] userData, boolean include) {
if (include) {
// This section should be updated with new data
writer.print(section);
for (String data : userData) {
writer.print("," + data);
}
writer.println();
} else if (existingData.containsKey(section)) {
// This section should be preserved as-is
String[] parts = existingData.get(section);
writer.print(parts[0] + "," + parts[1]); // Section and Sub-Section
// Add the remaining data columns
for (int i = 2; i < parts.length; i++) {
writer.print("," + parts[i]);
}
writer.println();
} else {
// Section doesn't exist and shouldn't be included - do nothing
}
}
}