From 824cdcbe4c3422793f733e5ca6c721c70c27356a Mon Sep 17 00:00:00 2001 From: diana Date: Sat, 5 Jan 2013 17:49:28 +0200 Subject: [PATCH 1/3] Fix edit / save bugs. --- src/element_actions/PopupListener.java | 106 ++-- src/element_actions/ViewText.java | 188 ++++++- src/gui/LayoutGUI.java | 674 ++++++++++++------------- 3 files changed, 573 insertions(+), 395 deletions(-) diff --git a/src/element_actions/PopupListener.java b/src/element_actions/PopupListener.java index b360145..1d54ece 100644 --- a/src/element_actions/PopupListener.java +++ b/src/element_actions/PopupListener.java @@ -1,53 +1,53 @@ -package element_actions; - -import gui.ElementJPanel; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import parser.LayoutParser; - -/** - * Button listener pentru salvare modificari. - * - * @author Unknown-Revengers - */ -public class PopupListener implements ActionListener { - - private final ElementJPanel panel; - - private final LayoutParser layoutParser; - - /** - * Constructor. - * - * @param panel - */ - public PopupListener(ElementJPanel panel, LayoutParser lp) { - this.panel = panel; - this.layoutParser = lp; - } - - @Override - public void actionPerformed(ActionEvent e) { - final String action = e.getActionCommand(); - - Thread actionThread = new Thread() { - @Override - public void run() { - try { - if (action.compareTo(ElementActions.S_OCR.toString()) == 0) { - new GetText(panel, layoutParser); - } - else if (action.compareTo(ElementActions.S_TEXT.toString()) == 0) { - new ViewText(panel); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - }; - - actionThread.start(); - } -} +package element_actions; + +import gui.ElementJPanel; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import parser.LayoutParser; + +/** + * Button listener pentru salvare modificari. + * + * @author Unknown-Revengers + */ +public class PopupListener implements ActionListener { + + private ElementJPanel panel; + + private LayoutParser layoutParser; + + /** + * Constructor. + * + * @param panel + */ + public PopupListener(ElementJPanel panel, LayoutParser lp) { + this.panel = panel; + this.layoutParser = lp; + } + + @Override + public void actionPerformed(ActionEvent e) { + final String action = e.getActionCommand(); + + Thread actionThread = new Thread() { + @Override + public void run() { + try { + if (action.compareTo(ElementActions.S_OCR.toString()) == 0) { + new GetText(panel, layoutParser); + } + else if (action.compareTo(ElementActions.S_TEXT.toString()) == 0) { + new ViewText(panel); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + + actionThread.start(); + } +} diff --git a/src/element_actions/ViewText.java b/src/element_actions/ViewText.java index 5a37d9d..4464e21 100644 --- a/src/element_actions/ViewText.java +++ b/src/element_actions/ViewText.java @@ -7,6 +7,9 @@ import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; @@ -14,6 +17,9 @@ import javax.swing.JScrollPane; import javax.swing.JTextArea; +import parser.LayoutParserTreeElement; +import tree.GenericTreeNode; + /** * @author Unknown-Revengers * @@ -59,7 +65,7 @@ public ViewText(ElementJPanel panel) { contentPanel = this.getContentPane(); // Adauga textul elementului la frame. - this.addText(elementPanel.element.getData().text); + this.addText(); // Adauga buton. this.addButton(); @@ -83,7 +89,8 @@ private void addButton() { @Override public void actionPerformed(ActionEvent e) { // Save text. - elementPanel.element.getData().text = descriptionArea.getText(); + ViewText.this.changeText(elementPanel.element, + descriptionArea.getText()); frame.dispose(); } @@ -94,15 +101,120 @@ public void actionPerformed(ActionEvent e) { } /** - * Adauga text la fereastra. + * Salveaza modificarile facute in arbore. * * @param text - * Textul de adaugat. + * Textul de salvat in arbore. */ - private void addText(String text) { + private void changeText(GenericTreeNode element, + String text) { + /* + * Daca elementul curent este nod frunza, modifica atributul text. + */ + if (element.getData().elementType.toString().compareTo("String") == 0) { + element.getData().text = text; + return; + } + + /* + * Daca TextBlock sau TextLine are doar o componenta + * (textComponents.length = 0) atunci aceasta este text. + */ + String[] textComponents = { text }; + + if (element.getData().elementType.toString().compareTo("TextBlock") == 0 + && text.contains("\n")) { + // Split text in lines. + textComponents = text.split("\n"); + + } else if (element.getData().elementType.toString().compareTo( + "TextLine") == 0) { + + if (text.contains("\n")) { + text = text.replace("\n", " "); + } + + text = text.trim(); + text = text.replaceAll("( )+", " "); + textComponents = text.split(" "); + } + + // Ia copii elementului curent. + List> children = element + .getChildren(); + + // Sorteaza dupa top. + Collections.sort(children, new ElementComparator()); + + // Adauga si modifica text in arbore. + for (int i = 0; i < textComponents.length; i++) { + if (children.size() == i + 1 + && element.getData().elementType.toString().compareTo( + "TextBlock") == 0) { + /* + * Daca numarul de noduri TextLine din TextBlock este mai mare + * decat numarul de noduri TextLine existente in arbore, adauga + * ultimile TextLine la ultimul nod TextLine din arbore. + */ + for (int j = i + 1; j < textComponents.length; j++) { + textComponents[i] = textComponents[i].concat(" ") + .concat(textComponents[j]); + } + + textComponents[i] = textComponents[i].trim(); + textComponents[i] = textComponents[i].replaceAll("( )+", " "); + + this.changeText(children.get(i), textComponents[i]); + break; + + } else if (children.size() > i) { + // Schimba textul din nodul existent children.get(i). + this.changeText(children.get(i), textComponents[i]); + + } else if (element.getData().elementType.toString().compareTo( + "TextLine") == 0) { + // Creaza frunze (elemente de tipul String). + LayoutParserTreeElement frunza = new LayoutParserTreeElement(); + frunza.text = textComponents[i]; + frunza.elementType = parser.LayoutParserTreeElement.ElementType.STRING; + + GenericTreeNode x = new GenericTreeNode(); + x.setData(frunza); + + element.addChild(x); + } + } + + // Sterge text din arbore. + if (children.size() > textComponents.length) { + for (int i = textComponents.length; i < children.size(); i++) { + // Daca este frunza, sterge nodul + if (children.get(i).getData().elementType.toString().compareTo( + "String") == 0) { + element.removeChildAt(i); + } + + // Daca este TextLine sterge frunzele. + else if (children.get(i).getData().elementType.toString() + .compareTo( + "TextLine") == 0) { + for (int j = 0; j < children.get(i).getNumberOfChildren(); j++) { + children.get(i).removeChildAt(j); + } + } + } + } + } + + /** + * Adauga text la fereastra. + */ + private void addText() { // New Panel. JPanel panel = new JPanel(); + String text = this.generateText(elementPanel.element); + // Creaza Text Area pentru text. descriptionArea = new JTextArea(text); descriptionArea.setLineWrap(true); @@ -121,6 +233,72 @@ private void addText(String text) { contentPanel.add(panel, BorderLayout.CENTER); } + /** + * Genereaza textul pentru elementul curent. + * + * @param element + * Elementul curent. + * @return String Textul elementului. + */ + @SuppressWarnings("unchecked") + private String generateText( + GenericTreeNode element) { + + // Daca elementul este nod frunza returneaza textul. + if (element.getData().elementType.toString().compareTo("String") == 0) { + return element.getData().text; + } + + // Ia copii elementului curent. + List> children = element + .getChildren(); + + // Sorteaza dupa top. + Collections.sort(children, new ElementComparator()); + + String text = ""; + for (GenericTreeNode child : children) { + text = text.concat(this.generateText(child)); + if (child.getData().elementType.toString().compareTo("TextLine") == 0) { + text = text.concat("\n"); + } + else if (child.getData().elementType.toString().compareTo("String") == 0) { + text = text.concat(" "); + } + } + + // Remove space or newline added after last component. + text = text.trim(); + return text; + } + + /** + * @author Unknown-Revengers + * + * Comparator Class for Elements. + */ + @SuppressWarnings("rawtypes") + public class ElementComparator implements Comparator { + @SuppressWarnings("unchecked") + @Override + public int compare(Object node1, Object node2) { + // Nu compara nodurile frunza, ele nu au top. + if (((GenericTreeNode) node1).getData().elementType + .toString().compareTo("String") != 0) { + int top1 = ((GenericTreeNode) node1) + .getData().top; + int top2 = ((GenericTreeNode) node2) + .getData().top; + + if (top1 != top2) { + return top1 > top2 ? -1 : 1; + } + } + + return 0; + } + } + /** * Initializeaza frame. */ diff --git a/src/gui/LayoutGUI.java b/src/gui/LayoutGUI.java index 9d3912b..aa15875 100644 --- a/src/gui/LayoutGUI.java +++ b/src/gui/LayoutGUI.java @@ -1,337 +1,337 @@ -package gui; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Frame; -import java.awt.GraphicsConfiguration; -import java.awt.Rectangle; -import java.awt.event.ActionListener; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.List; - -import javax.imageio.ImageIO; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPopupMenu; -import javax.swing.JScrollPane; -import javax.swing.ScrollPaneConstants; -import javax.swing.border.LineBorder; - -import page_actions.NumeroteazaButtonListener; -import page_actions.SalveazaButtonListener; -import parser.LayoutParser; -import parser.LayoutParserTreeElement; -import sun.java2d.SunGraphicsEnvironment; -import tree.GenericTreeNode; -import tree.GenericTreeTraversalOrderEnum; -import element_actions.BlockMouseListener; -import element_actions.ElementActions; -import element_actions.PopupListener; -import elements_actions.ActionButtonListener; -import elements_actions.ComponentComboListener; -import elements_actions.ElementsActions; - -/** - * Interfata grafica (ar fi recomandat ca pentru fiecare TODO sa existe o metoda - * / mai multe care fac acel lucru. Astfel, constructorul nu va avea sute de - * linii). Probabil e bine ca listenerele sa fie declarate in alte fisiere, din - * acelasi motiv. - * - * @author Unknown-Revengers - */ -@SuppressWarnings("serial") -public class LayoutGUI extends JFrame { - /** - * Layout parser. - */ - public final LayoutParser layoutParser; - - /** - * Imaginea ce este incarcata. - */ - private final BufferedImage image; - - /** - * Panelul in care se deseneaza imaginea. - */ - private DrawPanel draw; - - /** - * Scroll pane-ul in care se pun elementele din imagine. - */ - private JScrollPane scrollPane; - - public VisibleElements visibleElements; - - /** - * Constructor. - * - * @param layoutParser - * @throws IOException - */ - public LayoutGUI(LayoutParser layoutParser) throws IOException { - - this.layoutParser = layoutParser; - - // Incarca imaginea in fereastra. Trebuie luata din layoutParser - // imaginea. - File f = new File(this.layoutParser.imagePath); - this.image = ImageIO.read(f); - - // Initializeaza fereastra. - this.initFrame(); - - // Incarca zona in care se deseanza. - this.loadDrawZone(); - - // Adauga filtre si actiuni pentru document/elemente. - this.addFilters(); - - // Incarca elementele din pagina. - this.loadElements(VisibleElements.S_BLOCK); - - // Actiuni finale asupra documentului. - this.addFinalActions(); - - // Afiseaza fereastra. - this.setVisible(true); - } - - /** - * Initializeaza fereastra - * - * @return void - */ - private void initFrame() { - - // Seteaza layout. - getContentPane().setLayout(null); - - // Seteaza window maximized. - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setResizable(false); - this.setUndecorated(false); - this.pack(); - GraphicsConfiguration config = this.getGraphicsConfiguration(); - Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config - .getDevice()); - this.setExtendedState(Frame.MAXIMIZED_BOTH); - this.setMaximizedBounds(new Rectangle(0, 0, usableBounds.width, - usableBounds.height)); - - // Info label 1. - JLabel lblNewLabel = new JLabel( - "Pentru a selecta mai multe componente se va da click pe o componenta. " - + "Click pe o componenta selectata o va deselecta."); - lblNewLabel.setBounds(20, 50, this.getMaximizedBounds().width - 40, 15); - getContentPane().add(lblNewLabel); - - // Info label 2. - JLabel lblClickDreaptaPe = new JLabel( - "Click dreapta pe o componenta pentru actiunile specifice componentei."); - lblClickDreaptaPe.setBounds(20, 65, - this.getMaximizedBounds().width - 40, 15); - getContentPane().add(lblClickDreaptaPe); - } - - /** - * Inizializeaza zona in care se va desena. - * - * @return void - */ - private void loadDrawZone() { - // Initializeaza draw panel. - draw = new DrawPanel(image); - draw.setPreferredSize(new Dimension(image.getWidth(this), image - .getHeight(this))); - draw.setLayout(null); - - // Inizializeaza scroll panel si adauga draw panel in el. - scrollPane = new JScrollPane(draw); - scrollPane - .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); - scrollPane - .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - scrollPane.setBounds(20, 95, this.getMaximizedBounds().width - 40, - this.getMaximizedBounds().height - 180); - - // Adauga scroll panel in fereastra. - getContentPane().add(scrollPane); - } - - /** - * Incarca elementele in fereastra parsand fisierul de layout (se folosesc - * functii din this.layoutParser) - * - * @return void - */ - public void loadElements(VisibleElements type) { - - this.visibleElements = type; - - // Remove all drawed elements. - draw.removeAll(); - - List> list = this.layoutParser.XMLTree - .build(GenericTreeTraversalOrderEnum.PRE_ORDER); - - // Go through all elements. - for (int i = 0; i < list.size(); i++) { - - LayoutParserTreeElement e = list.get(i).getData(); - - // Check if element is of selected type. - if (e.elementType == type.toType()) { - - ElementJPanel panel = new ElementJPanel(list.get(i)); - panel.addMouseListener(new BlockMouseListener()); - panel.setBorder(new LineBorder(Color.GREEN)); - panel.setOpaque(false); - - // Set height and width so that the element is visible.. - int width = e.right - e.left > 1 ? e.right - e.left : 3; - int height = e.bottom - e.top > 1 ? e.bottom - e.top : 3; - - // Check direction. - if (this.layoutParser.direction.compareTo("descending") == 0) { - panel.setBounds(e.left, e.top, width, height); - } - else { - int m_height = this.image.getHeight(this); - panel.setBounds(e.left, m_height - e.bottom, width, height); - } - - // Draw panel - draw.add(panel); - - // Create the popup menu for the current panel - JPopupMenu popupMenu = new JPopupMenu(); - - /* - * Action listener pentru popupMenu Primeste ca parametru - * ElementJPanel pentru a extrage LayoutParserTreeElement - */ - ActionListener actionListener = new PopupListener(panel, - layoutParser); - - // Face analiza OCR. - JMenuItem ocrItem = new JMenuItem( - ElementActions.S_OCR.toString()); - ocrItem.addActionListener(actionListener); - popupMenu.add(ocrItem); - - // Sparge blocul de text orizontal. - JMenuItem splitItemH = new JMenuItem( - ElementActions.S_BREAK_H.toString()); - splitItemH.addActionListener(actionListener); - popupMenu.add(splitItemH); - - // Sparge blocul de text veritcal. - JMenuItem splitItemV = new JMenuItem( - ElementActions.S_BREAK_V.toString()); - splitItemV.addActionListener(actionListener); - popupMenu.add(splitItemV); - - // Marcheaza blocul de text ca fiind numar pagina. - JMenuItem paginaItem = new JMenuItem( - ElementActions.S_PAGE.toString()); - paginaItem.addActionListener(actionListener); - popupMenu.add(paginaItem); - - // Marcheaza blocul de text ca fiind numar pagina. - JMenuItem deleteItem = new JMenuItem( - ElementActions.S_DELETE.toString()); - deleteItem.addActionListener(actionListener); - popupMenu.add(deleteItem); - - // Vezi textul. - JMenuItem textItem = new JMenuItem( - ElementActions.S_TEXT.toString()); - textItem.addActionListener(actionListener); - popupMenu.add(textItem); - - panel.setComponentPopupMenu(popupMenu); - } - } - - } - - /** - * TODO Adauga filtre pentru selectia elementelor din imagine. - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void addFilters() { - // Label componentente. - JLabel lblComponente = new JLabel("Componente:"); - lblComponente.setBounds(20, 20, 75, 20); - getContentPane().add(lblComponente); - - /* - * Dropdown componenta - atunci cand se schimba selectia, trebui sa se - * schimbe si ceea ce este afisat peste imagine (litere, randuri sau - * blocuri). - */ - JComboBox comboElements = new JComboBox(); - comboElements.setModel(new DefaultComboBoxModel(new String[] { - VisibleElements.S_BLOCK.toString(), - VisibleElements.S_LINE.toString() })); - // Adauga listener pentru combo cu componente. - comboElements.addActionListener(new ComponentComboListener(this)); - comboElements.setBounds(105, 20, 125, 20); - getContentPane().add(comboElements); - - // Label actiuni posibile pentru selectia curenta. - JLabel lblActiuni = new JLabel("Actiuni:"); - lblActiuni.setBounds(this.getMaximizedBounds().width - 310, 20, 50, 25); - getContentPane().add(lblActiuni); - - /* - * Se poate face (DOAR PENTRU COMPONENTELE SELECTATE). Componentele - * selectate pot fi luate verificand daca in tooltip este scris - * selected. Vezi mouseClicked din BlockMouseListener. - analiza ocr - - * unire componente - spargere componente - */ - JComboBox comboBox = new JComboBox(); - comboBox.setModel(new DefaultComboBoxModel(new String[] { - ElementsActions.S_OCR.toString(), - ElementsActions.S_GLUE.toString() })); - comboBox.setBounds(this.getMaximizedBounds().width - 250, 20, 160, 25); - getContentPane().add(comboBox); - - // OK pentru actiunile posibile. - JButton btnNewButton = new JButton("OK"); - btnNewButton - .setBounds(this.getMaximizedBounds().width - 80, 20, 60, 25); - // Adauga listener pentru combo cu actiuni. - btnNewButton.addActionListener(new ActionButtonListener(comboBox, draw, - this)); - getContentPane().add(btnNewButton); - } - - /** - * TODO Buton pentru salvat schimbarile facute intr-un fisier de output. - */ - private void addFinalActions() { - // TODO Ruleaza modul de numerotare a paginii. - JButton btnNumeroteaza = new JButton("Numeroteaza pagina"); - btnNumeroteaza.setBounds(this.getMaximizedBounds().width - 290, - this.getMaximizedBounds().height - 70, 170, 23); - // Adauga listener pentru buton de numerotare pagina. - btnNumeroteaza.addActionListener(new NumeroteazaButtonListener()); - getContentPane().add(btnNumeroteaza); - - // TODO Salveaza schimbarile facute intr-un fisier de output. - JButton btnSalveaza = new JButton("Salveaza"); - btnSalveaza.setBounds(this.getMaximizedBounds().width - 110, - this.getMaximizedBounds().height - 70, 90, 23); - // Adauga listener pentru buton de numerotare pagina. - btnSalveaza.addActionListener(new SalveazaButtonListener()); - getContentPane().add(btnSalveaza); - } -} +package gui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.Rectangle; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.imageio.ImageIO; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.ScrollPaneConstants; +import javax.swing.border.LineBorder; + +import page_actions.NumeroteazaButtonListener; +import page_actions.SalveazaButtonListener; +import parser.LayoutParser; +import parser.LayoutParserTreeElement; +import sun.java2d.SunGraphicsEnvironment; +import tree.GenericTreeNode; +import tree.GenericTreeTraversalOrderEnum; +import element_actions.BlockMouseListener; +import element_actions.ElementActions; +import element_actions.PopupListener; +import elements_actions.ActionButtonListener; +import elements_actions.ComponentComboListener; +import elements_actions.ElementsActions; + +/** + * Interfata grafica (ar fi recomandat ca pentru fiecare TODO sa existe o metoda + * / mai multe care fac acel lucru. Astfel, constructorul nu va avea sute de + * linii). Probabil e bine ca listenerele sa fie declarate in alte fisiere, din + * acelasi motiv. + * + * @author Unknown-Revengers + */ +@SuppressWarnings("serial") +public class LayoutGUI extends JFrame { + /** + * Layout parser. + */ + public LayoutParser layoutParser; + + /** + * Imaginea ce este incarcata. + */ + private BufferedImage image; + + /** + * Panelul in care se deseneaza imaginea. + */ + private DrawPanel draw; + + /** + * Scroll pane-ul in care se pun elementele din imagine. + */ + private JScrollPane scrollPane; + + public VisibleElements visibleElements; + + /** + * Constructor. + * + * @param layoutParser + * @throws IOException + */ + public LayoutGUI(LayoutParser layoutParser) throws IOException { + + this.layoutParser = layoutParser; + + // Incarca imaginea in fereastra. Trebuie luata din layoutParser + // imaginea. + File f = new File(this.layoutParser.imagePath); + this.image = ImageIO.read(f); + + // Initializeaza fereastra. + this.initFrame(); + + // Incarca zona in care se deseanza. + this.loadDrawZone(); + + // Adauga filtre si actiuni pentru document/elemente. + this.addFilters(); + + // Incarca elementele din pagina. + this.loadElements(VisibleElements.S_BLOCK); + + // Actiuni e asupra documentului. + this.addActions(); + + // Afiseaza fereastra. + this.setVisible(true); + } + + /** + * Initializeaza fereastra + * + * @return void + */ + private void initFrame() { + + // Seteaza layout. + getContentPane().setLayout(null); + + // Seteaza window maximized. + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setResizable(false); + this.setUndecorated(false); + this.pack(); + GraphicsConfiguration config = this.getGraphicsConfiguration(); + Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config + .getDevice()); + this.setExtendedState(Frame.MAXIMIZED_BOTH); + this.setMaximizedBounds(new Rectangle(0, 0, usableBounds.width, + usableBounds.height)); + + // Info label 1. + JLabel lblNewLabel = new JLabel( + "Pentru a selecta mai multe componente se va da click pe o componenta. " + + "Click pe o componenta selectata o va deselecta."); + lblNewLabel.setBounds(20, 50, this.getMaximizedBounds().width - 40, 15); + getContentPane().add(lblNewLabel); + + // Info label 2. + JLabel lblClickDreaptaPe = new JLabel( + "Click dreapta pe o componenta pentru actiunile specifice componentei."); + lblClickDreaptaPe.setBounds(20, 65, + this.getMaximizedBounds().width - 40, 15); + getContentPane().add(lblClickDreaptaPe); + } + + /** + * Inizializeaza zona in care se va desena. + * + * @return void + */ + private void loadDrawZone() { + // Initializeaza draw panel. + draw = new DrawPanel(image); + draw.setPreferredSize(new Dimension(image.getWidth(this), image + .getHeight(this))); + draw.setLayout(null); + + // Inizializeaza scroll panel si adauga draw panel in el. + scrollPane = new JScrollPane(draw); + scrollPane + .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane + .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane.setBounds(20, 95, this.getMaximizedBounds().width - 40, + this.getMaximizedBounds().height - 180); + + // Adauga scroll panel in fereastra. + getContentPane().add(scrollPane); + } + + /** + * Incarca elementele in fereastra parsand fisierul de layout (se folosesc + * functii din this.layoutParser) + * + * @return void + */ + public void loadElements(VisibleElements type) { + + this.visibleElements = type; + + // Remove all drawed elements. + draw.removeAll(); + + List> list = this.layoutParser.XMLTree + .build(GenericTreeTraversalOrderEnum.PRE_ORDER); + + // Go through all elements. + for (int i = 0; i < list.size(); i++) { + + LayoutParserTreeElement e = list.get(i).getData(); + + // Check if element is of selected type. + if (e.elementType == type.toType()) { + + ElementJPanel panel = new ElementJPanel(list.get(i)); + panel.addMouseListener(new BlockMouseListener()); + panel.setBorder(new LineBorder(Color.GREEN)); + panel.setOpaque(false); + + // Set height and width so that the element is visible.. + int width = e.right - e.left > 1 ? e.right - e.left : 3; + int height = e.bottom - e.top > 1 ? e.bottom - e.top : 3; + + // Check direction. + if (this.layoutParser.direction.compareTo("descending") == 0) { + panel.setBounds(e.left, e.top, width, height); + } + else { + int m_height = this.image.getHeight(this); + panel.setBounds(e.left, m_height - e.bottom, width, height); + } + + // Draw panel + draw.add(panel); + + // Create the popup menu for the current panel + JPopupMenu popupMenu = new JPopupMenu(); + + /* + * Action listener pentru popupMenu Primeste ca parametru + * ElementJPanel pentru a extrage LayoutParserTreeElement + */ + ActionListener actionListener = new PopupListener(panel, + layoutParser); + + // Face analiza OCR. + JMenuItem ocrItem = new JMenuItem( + ElementActions.S_OCR.toString()); + ocrItem.addActionListener(actionListener); + popupMenu.add(ocrItem); + + // Sparge blocul de text orizontal. + JMenuItem splitItemH = new JMenuItem( + ElementActions.S_BREAK_H.toString()); + splitItemH.addActionListener(actionListener); + popupMenu.add(splitItemH); + + // Sparge blocul de text veritcal. + JMenuItem splitItemV = new JMenuItem( + ElementActions.S_BREAK_V.toString()); + splitItemV.addActionListener(actionListener); + popupMenu.add(splitItemV); + + // Marcheaza blocul de text ca fiind numar pagina. + JMenuItem paginaItem = new JMenuItem( + ElementActions.S_PAGE.toString()); + paginaItem.addActionListener(actionListener); + popupMenu.add(paginaItem); + + // Marcheaza blocul de text ca fiind numar pagina. + JMenuItem deleteItem = new JMenuItem( + ElementActions.S_DELETE.toString()); + deleteItem.addActionListener(actionListener); + popupMenu.add(deleteItem); + + // Vezi textul. + JMenuItem textItem = new JMenuItem( + ElementActions.S_TEXT.toString()); + textItem.addActionListener(actionListener); + popupMenu.add(textItem); + + panel.setComponentPopupMenu(popupMenu); + } + } + + } + + /** + * TODO Adauga filtre pentru selectia elementelor din imagine. + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void addFilters() { + // Label componentente. + JLabel lblComponente = new JLabel("Componente:"); + lblComponente.setBounds(20, 20, 75, 20); + getContentPane().add(lblComponente); + + /* + * Dropdown componenta - atunci cand se schimba selectia, trebui sa se + * schimbe si ceea ce este afisat peste imagine (litere, randuri sau + * blocuri). + */ + JComboBox comboElements = new JComboBox(); + comboElements.setModel(new DefaultComboBoxModel(new String[] { + VisibleElements.S_BLOCK.toString(), + VisibleElements.S_LINE.toString() })); + // Adauga listener pentru combo cu componente. + comboElements.addActionListener(new ComponentComboListener(this)); + comboElements.setBounds(105, 20, 125, 20); + getContentPane().add(comboElements); + + // Label actiuni posibile pentru selectia curenta. + JLabel lblActiuni = new JLabel("Actiuni:"); + lblActiuni.setBounds(this.getMaximizedBounds().width - 310, 20, 50, 25); + getContentPane().add(lblActiuni); + + /* + * Se poate face (DOAR PENTRU COMPONENTELE SELECTATE). Componentele + * selectate pot fi luate verificand daca in tooltip este scris + * selected. Vezi mouseClicked din BlockMouseListener. - analiza ocr - + * unire componente - spargere componente + */ + JComboBox comboBox = new JComboBox(); + comboBox.setModel(new DefaultComboBoxModel(new String[] { + ElementsActions.S_OCR.toString(), + ElementsActions.S_GLUE.toString() })); + comboBox.setBounds(this.getMaximizedBounds().width - 250, 20, 160, 25); + getContentPane().add(comboBox); + + // OK pentru actiunile posibile. + JButton btnNewButton = new JButton("OK"); + btnNewButton + .setBounds(this.getMaximizedBounds().width - 80, 20, 60, 25); + // Adauga listener pentru combo cu actiuni. + btnNewButton.addActionListener(new ActionButtonListener(comboBox, draw, + this)); + getContentPane().add(btnNewButton); + } + + /** + * TODO Buton pentru salvat schimbarile facute intr-un fisier de output. + */ + private void addActions() { + // TODO Ruleaza modul de numerotare a paginii. + JButton btnNumeroteaza = new JButton("Numeroteaza pagina"); + btnNumeroteaza.setBounds(this.getMaximizedBounds().width - 290, + this.getMaximizedBounds().height - 70, 170, 23); + // Adauga listener pentru buton de numerotare pagina. + btnNumeroteaza.addActionListener(new NumeroteazaButtonListener()); + getContentPane().add(btnNumeroteaza); + + // TODO Salveaza schimbarile facute intr-un fisier de output. + JButton btnSalveaza = new JButton("Salveaza"); + btnSalveaza.setBounds(this.getMaximizedBounds().width - 110, + this.getMaximizedBounds().height - 70, 90, 23); + // Adauga listener pentru buton de numerotare pagina. + btnSalveaza.addActionListener(new SalveazaButtonListener()); + getContentPane().add(btnSalveaza); + } +} From e8ffd5de8c35c69576ac50aa17576f436ea0d72a Mon Sep 17 00:00:00 2001 From: diana Date: Sat, 5 Jan 2013 19:39:49 +0200 Subject: [PATCH 2/3] User can delete text while editing. --- src/element_actions/ViewText.java | 52 +++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/element_actions/ViewText.java b/src/element_actions/ViewText.java index a9e88e0..0f0717d 100644 --- a/src/element_actions/ViewText.java +++ b/src/element_actions/ViewText.java @@ -187,21 +187,38 @@ private void changeText(GenericTreeNode element, // Sterge text din arbore. if (children.size() > textComponents.length) { - for (int i = textComponents.length; i < children.size(); i++) { - // Daca este frunza, sterge nodul - if (children.get(i).getData().elementType.toString().compareTo( - "String") == 0) { - element.removeChildAt(i); - } + this.deleteText(element, textComponents.length); + } + } - // Daca este TextLine sterge frunzele. - else if (children.get(i).getData().elementType.toString() - .compareTo( - "TextLine") == 0) { - for (int j = 0; j < children.get(i).getNumberOfChildren(); j++) { - children.get(i).removeChildAt(j); - } - } + /** + * Sterge noduri frunza daca la editare s-au sters cuvinte. + * + * @param element + * Elementul din care s-au sters cuvinte. + * @param textLength + * Numarul de elemente ramase. + */ + private void deleteText(GenericTreeNode element, + int textLength) { + // Ia copii elementului curent. + List> children = element + .getChildren(); + + // Sorteaza dupa top. + Collections.sort(children, new ElementComparator()); + + for (int i = textLength; i < children.size(); i++) { + // Daca este frunza, sterge nodul + if (children.get(i).getData().elementType.toString().compareTo( + "String") == 0) { + element.removeChildAt(i); + + // One child removed, size drops by 1. + i--; + + } else { + this.deleteText(children.get(i), 0); } } } @@ -267,8 +284,11 @@ else if (child.getData().elementType.toString().compareTo("String") == 0) { } } - // Remove space or newline added after last component. - text = text.trim(); + // Remove space and new line added only after last component. + text = text.replaceAll(" $", ""); + if (element.getData().elementType.toString().compareTo("TextBlock") == 0) { + text = text.substring(0, text.length() - 1); + } return text; } From b4cb81aa50f407c303337e3fdc2ed9ff9a48b5e4 Mon Sep 17 00:00:00 2001 From: diana Date: Sat, 5 Jan 2013 21:59:37 +0200 Subject: [PATCH 3/3] Muta metodele pentru actiuni pe text in parser.TextActions --- src/element_actions/ViewText.java | 202 +---------------------------- src/parser/TextActions.java | 208 ++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 199 deletions(-) create mode 100644 src/parser/TextActions.java diff --git a/src/element_actions/ViewText.java b/src/element_actions/ViewText.java index 0f0717d..d8a8f29 100644 --- a/src/element_actions/ViewText.java +++ b/src/element_actions/ViewText.java @@ -7,9 +7,6 @@ import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; @@ -17,8 +14,7 @@ import javax.swing.JScrollPane; import javax.swing.JTextArea; -import parser.LayoutParserTreeElement; -import tree.GenericTreeNode; +import parser.TextActions; /** * @author Unknown-Revengers @@ -89,7 +85,7 @@ private void addButton() { @Override public void actionPerformed(ActionEvent e) { // Save text. - ViewText.this.changeText(elementPanel.element, + TextActions.saveText(elementPanel.element, descriptionArea.getText()); frame.dispose(); @@ -100,129 +96,6 @@ public void actionPerformed(ActionEvent e) { contentPanel.add(panel, BorderLayout.SOUTH); } - /** - * Salveaza modificarile facute in arbore. - * - * @param text - * Textul de salvat in arbore. - */ - private void changeText(GenericTreeNode element, - String text) { - /* - * Daca elementul curent este nod frunza, modifica atributul text. - */ - if (element.getData().elementType.toString().compareTo("String") == 0) { - element.getData().text = text; - return; - } - - /* - * Daca TextBlock sau TextLine are doar o componenta - * (textComponents.length = 0) atunci aceasta este text. - */ - String[] textComponents = { text }; - - if (element.getData().elementType.toString().compareTo("TextBlock") == 0 - && text.contains("\n")) { - // Split text in lines. - textComponents = text.split("\n"); - - } else if (element.getData().elementType.toString().compareTo( - "TextLine") == 0) { - - if (text.contains("\n")) { - text = text.replace("\n", " "); - } - - text = text.trim(); - text = text.replaceAll("( )+", " "); - textComponents = text.split(" "); - } - - // Ia copii elementului curent. - List> children = element - .getChildren(); - - // Sorteaza dupa top. - Collections.sort(children, new ElementComparator()); - - // Adauga si modifica text in arbore. - for (int i = 0; i < textComponents.length; i++) { - if (children.size() == i + 1 - && element.getData().elementType.toString().compareTo( - "TextBlock") == 0) { - /* - * Daca numarul de noduri TextLine din TextBlock este mai mare - * decat numarul de noduri TextLine existente in arbore, adauga - * ultimile TextLine la ultimul nod TextLine din arbore. - */ - for (int j = i + 1; j < textComponents.length; j++) { - textComponents[i] = textComponents[i].concat(" ") - .concat(textComponents[j]); - } - - textComponents[i] = textComponents[i].trim(); - textComponents[i] = textComponents[i].replaceAll("( )+", " "); - - this.changeText(children.get(i), textComponents[i]); - break; - - } else if (children.size() > i) { - // Schimba textul din nodul existent children.get(i). - this.changeText(children.get(i), textComponents[i]); - - } else if (element.getData().elementType.toString().compareTo( - "TextLine") == 0) { - // Creaza frunze (elemente de tipul String). - LayoutParserTreeElement frunza = new LayoutParserTreeElement(); - frunza.text = textComponents[i]; - frunza.elementType = parser.LayoutParserTreeElement.ElementType.STRING; - - GenericTreeNode x = new GenericTreeNode(); - x.setData(frunza); - - element.addChild(x); - } - } - - // Sterge text din arbore. - if (children.size() > textComponents.length) { - this.deleteText(element, textComponents.length); - } - } - - /** - * Sterge noduri frunza daca la editare s-au sters cuvinte. - * - * @param element - * Elementul din care s-au sters cuvinte. - * @param textLength - * Numarul de elemente ramase. - */ - private void deleteText(GenericTreeNode element, - int textLength) { - // Ia copii elementului curent. - List> children = element - .getChildren(); - - // Sorteaza dupa top. - Collections.sort(children, new ElementComparator()); - - for (int i = textLength; i < children.size(); i++) { - // Daca este frunza, sterge nodul - if (children.get(i).getData().elementType.toString().compareTo( - "String") == 0) { - element.removeChildAt(i); - - // One child removed, size drops by 1. - i--; - - } else { - this.deleteText(children.get(i), 0); - } - } - } - /** * Adauga text la fereastra. */ @@ -230,7 +103,7 @@ private void addText() { // New Panel. JPanel panel = new JPanel(); - String text = this.generateText(elementPanel.element); + String text = TextActions.getText(elementPanel.element); // Creaza Text Area pentru text. descriptionArea = new JTextArea(text); @@ -250,75 +123,6 @@ private void addText() { contentPanel.add(panel, BorderLayout.CENTER); } - /** - * Genereaza textul pentru elementul curent. - * - * @param element - * Elementul curent. - * @return String Textul elementului. - */ - @SuppressWarnings("unchecked") - private String generateText( - GenericTreeNode element) { - - // Daca elementul este nod frunza returneaza textul. - if (element.getData().elementType.toString().compareTo("String") == 0) { - return element.getData().text; - } - - // Ia copii elementului curent. - List> children = element - .getChildren(); - - // Sorteaza dupa top. - Collections.sort(children, new ElementComparator()); - - String text = ""; - for (GenericTreeNode child : children) { - text = text.concat(this.generateText(child)); - if (child.getData().elementType.toString().compareTo("TextLine") == 0) { - text = text.concat("\n"); - } - else if (child.getData().elementType.toString().compareTo("String") == 0) { - text = text.concat(" "); - } - } - - // Remove space and new line added only after last component. - text = text.replaceAll(" $", ""); - if (element.getData().elementType.toString().compareTo("TextBlock") == 0) { - text = text.substring(0, text.length() - 1); - } - return text; - } - - /** - * @author Unknown-Revengers - * - * Comparator Class for Elements. - */ - @SuppressWarnings("rawtypes") - public class ElementComparator implements Comparator { - @SuppressWarnings("unchecked") - @Override - public int compare(Object node1, Object node2) { - // Nu compara nodurile frunza, ele nu au top. - if (((GenericTreeNode) node1).getData().elementType - .toString().compareTo("String") != 0) { - int top1 = ((GenericTreeNode) node1) - .getData().top; - int top2 = ((GenericTreeNode) node2) - .getData().top; - - if (top1 != top2) { - return top1 > top2 ? -1 : 1; - } - } - - return 0; - } - } - /** * Initializeaza frame. */ diff --git a/src/parser/TextActions.java b/src/parser/TextActions.java new file mode 100644 index 0000000..8a47090 --- /dev/null +++ b/src/parser/TextActions.java @@ -0,0 +1,208 @@ +package parser; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import tree.GenericTreeNode; + +/** + * @author diana + * + */ +public class TextActions { + /** + * Genereaza textul pentru elementul curent. + * + * @param element + * Elementul curent. + * @return String Textul elementului. + */ + @SuppressWarnings("unchecked") + public static String getText( + GenericTreeNode element) { + + // Daca elementul este nod frunza returneaza textul. + if (element.getData().elementType.toString().compareTo("String") == 0) { + return element.getData().text; + } + + // Ia copii elementului curent. + List> children = element + .getChildren(); + + // Sorteaza dupa top. + Collections.sort(children, new ElementComparator()); + + String text = ""; + for (GenericTreeNode child : children) { + text = text.concat(getText(child)); + if (child.getData().elementType.toString().compareTo("TextLine") == 0) { + text = text.concat("\n"); + } + else if (child.getData().elementType.toString().compareTo("String") == 0) { + text = text.concat(" "); + } + } + + // Remove space and new line added only after last component. + text = text.replaceAll(" $", ""); + if (element.getData().elementType.toString().compareTo("TextBlock") == 0) { + text = text.substring(0, text.length() - 1); + } + return text; + } + + /** + * Salveaza modificarile facute in arbore. + * + * @param text + * Textul de salvat in arbore. + */ + public static void saveText( + GenericTreeNode element, + String text) { + /* + * Daca elementul curent este nod frunza, modifica atributul text. + */ + if (element.getData().elementType.toString().compareTo("String") == 0) { + element.getData().text = text; + return; + } + + /* + * Daca TextBlock sau TextLine are doar o componenta atunci aceasta este + * text. + */ + String[] textComponents = { text }; + + // Sparge textul dupa delimitatori. + if (element.getData().elementType.toString().compareTo("TextBlock") == 0 + && text.contains("\n")) { + // Split text in lines. + textComponents = text.split("\n"); + + } else if (element.getData().elementType.toString().compareTo( + "TextLine") == 0) { + + if (text.contains("\n")) { + text = text.replace("\n", " "); + } + + text = text.trim(); + text = text.replaceAll("( )+", " "); + textComponents = text.split(" "); + } + + // Ia copii elementului curent. + List> children = element + .getChildren(); + + // Sorteaza dupa top. + Collections.sort(children, new ElementComparator()); + + // Adauga si modifica text in arbore. + for (int i = 0; i < textComponents.length; i++) { + if (children.size() == i + 1 + && element.getData().elementType.toString().compareTo( + "TextBlock") == 0) { + /* + * Daca numarul de noduri TextLine din TextBlock este mai mare + * decat numarul de noduri TextLine existente in arbore, adauga + * ultimile TextLine la ultimul nod TextLine din arbore. + */ + for (int j = i + 1; j < textComponents.length; j++) { + textComponents[i] = textComponents[i].concat(" ") + .concat(textComponents[j]); + } + + textComponents[i] = textComponents[i].trim(); + textComponents[i] = textComponents[i].replaceAll("( )+", " "); + + saveText(children.get(i), textComponents[i]); + break; + + } else if (children.size() > i) { + // Schimba textul din nodul existent children.get(i). + saveText(children.get(i), textComponents[i]); + + } else if (element.getData().elementType.toString().compareTo( + "TextLine") == 0) { + // Creaza frunze (elemente de tipul String). + LayoutParserTreeElement frunza = new LayoutParserTreeElement(); + frunza.text = textComponents[i]; + frunza.elementType = parser.LayoutParserTreeElement.ElementType.STRING; + + GenericTreeNode x = new GenericTreeNode(); + x.setData(frunza); + + element.addChild(x); + } + } + + // Sterge text din arbore. + if (children.size() > textComponents.length) { + deleteText(element, textComponents.length); + } + } + + /** + * Sterge noduri frunza daca la editare s-au sters cuvinte. + * + * @param element + * Elementul din care s-au sters cuvinte. + * @param textLength + * Numarul de elemente ramase. + */ + private static void deleteText( + GenericTreeNode element, + int textLength) { + // Ia copii elementului curent. + List> children = element + .getChildren(); + + // Sorteaza dupa top. + Collections.sort(children, new ElementComparator()); + + for (int i = textLength; i < children.size(); i++) { + // Daca este frunza, sterge nodul + if (children.get(i).getData().elementType.toString().compareTo( + "String") == 0) { + element.removeChildAt(i); + + // One child removed, size drops by 1. + i--; + + } else { + deleteText(children.get(i), 0); + } + } + } + + /** + * @author Unknown-Revengers + * + * Comparator Class for Elements. + */ + @SuppressWarnings("rawtypes") + public static class ElementComparator implements Comparator { + @SuppressWarnings("unchecked") + @Override + public int compare(Object node1, Object node2) { + // Nu compara nodurile frunza, ele nu au top. + if (((GenericTreeNode) node1).getData().elementType + .toString().compareTo("String") != 0) { + int top1 = ((GenericTreeNode) node1) + .getData().top; + int top2 = ((GenericTreeNode) node2) + .getData().top; + + if (top1 != top2) { + return top1 > top2 ? -1 : 1; + } + } + + return 0; + } + } +}