📄 fjreport.java
字号:
package net.sf.fjreport;
import java.awt.Color;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Scrollable;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.xml.sax.SAXException;
import net.sf.fjreport.cell.Cell;
import net.sf.fjreport.cell.CellMouseControl;
import net.sf.fjreport.control.BaseControl;
import net.sf.fjreport.control.NewPageAction;
import net.sf.fjreport.control.NextPageAction;
import net.sf.fjreport.control.PrePageAction;
import net.sf.fjreport.control.RemovePageAction;
import net.sf.fjreport.io.FJReportIO;
import net.sf.fjreport.io.ReportFileFilter;
import net.sf.fjreport.line.Line;
import net.sf.fjreport.line.LineMouseControl;
import net.sf.fjreport.statusbar.HasStatus;
import net.sf.fjreport.statusbar.StatusChangeListener;
import net.sf.fjreport.util.CommonUtil;
import net.sf.fjreport.util.StringResource;
/**
* Create a report inherited from JPanel
* @author Frank Lewis
*
*/
public class FJReport extends JPanel implements Printable, Scrollable, HasStatus, MultiPage, Printer{
private Zoom zoom = new Zoom(1, 0, 0);
private PageFormat pageFormat;
private boolean editting;
private BaseControl operation;
private int state;
/**
* DRAWLINE_STATE, for designing report.
* <p>
* in line state, you can draw vertical or horizontal lines. Right press
* mouse and drag, when right button is released, a new line is drawn. Left
* click on a line to pick it. left double click on a line to set its style.
* <p/>
* When a line is picked (hight light with red color), left press mouse
* on it then drag can move the line to the desired position. Left press
* mouse on its end point then drag (to vertical line, buttom point is end;
* to horizontal line, right point is end), the line length will change.
* <p/>
* For quickly use, left double click on blank will create a horizontal
* line stretching from left border to right border with line.startPoint.y =
* mouseEvent.y, while right click on blank will create a vertical line
* stretching from top to bottom.
*/
public static final int DRAWLINE_STATE = 1;
/**
* CELL_STATE, can set cell's properties.
* <p/>
* Left double click on a cell to activate the cell edit dialog. there are
* currently 9 cell types. they are empty, label, textfield(sigle line
* edit), textarea(multi line edit), combobox, checkbox, datefiled, image,
* custom.
* <p/>
* When state is switched from line to cell, fjreport will update
* cells' position and size according to the lines change. the algorithm
* performance is about n*n, fast enough.
*/
public static final int CELL_STATE = 2;
/**
* edit state, for end user of your application.
* <p/>
* users can finish form-style report in edit state. they can input in the
* disigned grids report. What they see on the screen is what they get on
* a paper from printer. This is the main purpose of this package. To
* provide form-style report editor to user, something like MS Word.
*/
public static final int EDIT_STATE = 3;
/**
* READONLY_STATE, the initial state when a report is first craeted.
* It looks like edit_state, but can't accept user input.
*/
public static final int READONLY_STATE = 0;
private List<FJReportPage> pages = new ArrayList();
/**
* Current editing page of a multi-page report
*/
public FJReportPage currentPage;
private int currentPageIndex;
private JComboBox comboFont;
private JComboBox comboSize;
private FJReport instance;
private HashMap cellMap;
/**
* get current cell that gain the editing focus.
* @return the focused cell.
*/
public Cell getCurrentCell() {
return currentPage.currentCell;
}
/**
* set focused cell.
* @param currentCell the cell you want to set editing focus
*/
public void setCurrentCell(Cell currentCell) {
if (currentPage.currentCell != null) currentPage.currentCell.setSelected(false);
currentPage.currentCell = currentCell;
if (currentCell != null) {
currentCell.setSelected(true);
if (comboFont != null) comboFont.setSelectedItem(currentCell.getFont().getName());
if (comboSize != null) comboSize.setSelectedItem(String.valueOf(currentCell.getFont().getSize()));
}
}
/**
* clear all lines (except imageable borders) and cells in current page.
*/
public void clear(){
if (currentPage == null) return;
currentPage.hLines.clear();
currentPage.vLines.clear();
addBorders();
currentPage.cells.clear();
setPageFormat(pageFormat);
removeAll();
updateUI();
}
/**
* not implemented now
* @return editing
*/
public boolean isEditting() {
return editting;
}
/**
* not implemented now
* @param editting
*/
public void setEditting(boolean editting) {
this.editting = editting;
}
/**
* create a report with single page.
* <p/>
* pageformat is set to default. doublebuffered is true. Background color is
* set to white.
*/
public FJReport(){
super(null);
PrinterJob job = PrinterJob.getPrinterJob();
setPageFormat(job.validatePage(job.defaultPage()));
setDoubleBuffered(true);
insertPage();
setBackground(Color.WHITE);
instance = this;
// KeyboardFocusManager kbfm = KeyboardFocusManager.
// getCurrentKeyboardFocusManager();
// kbfm.addKeyEventDispatcher(new MyKeyboardManager());
}
/* (non-Javadoc)
* @see java.awt.print.Printable#print(java.awt.Graphics, java.awt.print.PageFormat, int)
*/
public int print(Graphics arg0, PageFormat arg1, int arg2) throws PrinterException {
// TODO Auto-generated method stub
if (pages == null || arg2 >= pages.size() || arg2 < 0)
return Printable.NO_SUCH_PAGE;
setCurrentPageIndex(arg2);
printPaint(arg0);
return 0;
}
private void printPaint(Graphics arg0) {
Iterator it;
Line line;
Graphics2D g2d = (Graphics2D)arg0;
// paintComponents(arg0);
if (currentPage.cells != null) {
it = currentPage.cells.iterator();
while (it.hasNext()) {
((Cell)it.next()).printRender(g2d);
}
}
it = currentPage.vLines.iterator();
while (it.hasNext()) {
line = (Line) it.next();
if (!line.isInVisible()) {
line.render(0, 0, g2d);
}
}
it = currentPage.hLines.iterator();
while (it.hasNext()) {
line = (Line) it.next();
if (!line.isInVisible()) line.render(0, 0, g2d);
}
}
/**
* @return page format of the report.
*/
public PageFormat getPageFormat() {
return pageFormat;
}
/**
* set page format of report.
* <p/>
* Position and length of all imageable borders will be adjusted
* to the new page format. The preferred size of report will also
* set to the size of page format.
* Note that if current page format equals the new page format,
* this function has no effect.
*
* @param pageFormat the new page format.
*/
public void setPageFormat(PageFormat pageFormat) {
if (CommonUtil.isPageEqual(this.pageFormat, pageFormat)) return;
int x = (int) pageFormat.getImageableX();
int y = (int) pageFormat.getImageableY();
int w = (int) pageFormat.getImageableWidth();
int h = (int) pageFormat.getImageableHeight();
x = x + Line.lineInterval - x % Line.lineInterval;
y = y + Line.lineInterval - y % Line.lineInterval;
w = w - Line.lineInterval - w % Line.lineInterval;
h = h - Line.lineInterval - h % Line.lineInterval;
Line line;
for (int i = 0; i < pages.size(); i++){
FJReportPage page = (FJReportPage)pages.get(i);
for (int j = page.hLines.size() - 1; j >= 0 ; j--){
line = (Line) page.hLines.get(j);
if (line.getBorderType() == Line.BORDER_UP) {
line.setStartPoint(new Point(x, y));
line.setLength(w);
} else if (line.getBorderType() == Line.BORDER_DOWN) {
line.setStartPoint(new Point(x, y + h));
line.setLength(w);
}
}
for (int j = page.vLines.size() - 1; j >= 0 ; j--){
line = (Line) page.vLines.get(j);
if (line.getBorderType() == Line.BORDER_LEFT) {
line.setStartPoint(new Point(x, y));
line.setLength(h);
} else if (line.getBorderType() == Line.BORDER_RIGHT) {
line.setStartPoint(new Point(x + w, y));
line.setLength(h);
}
}
}
if (this.pageFormat != null
&& !CommonUtil.isPageEqual(this.pageFormat, pageFormat)) {
int newx = x;
int newy = y;
int neww = w;
int newh = h;
x = (int) this.pageFormat.getImageableX();
y = (int) this.pageFormat.getImageableY();
w = (int) this.pageFormat.getImageableWidth();
h = (int) this.pageFormat.getImageableHeight();
x = x + Line.lineInterval - x % Line.lineInterval;
y = y + Line.lineInterval - y % Line.lineInterval;
w = w - Line.lineInterval - w % Line.lineInterval;
h = h - Line.lineInterval - h % Line.lineInterval;
FJReportPage page, cPage;
cPage = currentPage;
List lines;
for(int i = 0; i < pages.size(); i++) {
page = pages.get(i);
lines = page.vLines;
for(int j = 0; j < lines.size(); j++) {
line = (Line) lines.get(j);
if (line.getX() == x) {
line.setStartPoint(new Point(newx, line.getY()));
} else if (line.getX() == x + w) {
line.setStartPoint(new Point(newx + neww, line.getY()));
}
if (line.getY() == y) {
line.setStartPoint(new Point(line.getX(), newy));
line.setLength(line.getLength() - newy + y);
}
if (line.getEndY() == y + h) {
line.setLength(line.getLength() + (newy + newh) - (y + h));
}
}
lines = page.hLines;
for(int j = 0; j < lines.size(); j++) {
line = (Line) lines.get(j);
if (line.getY() == y) {
line.setStartPoint(new Point(line.getX(), newy));
} else if (line.getY() == y + h) {
line.setStartPoint(new Point(line.getX(), newy + newh));
}
if (line.getX() == x) {
line.setStartPoint(new Point(newx, line.getY()));
line.setLength(line.getLength() - newx + x);
}
if (line.getEndX() == x + w) {
line.setLength(line.getLength() + (newx + neww) - (x + w));
}
}
currentPage = page;
reCalcCells();
}
currentPage = cPage;
}
this.pageFormat = pageFormat;
setPreferredSize(new Dimension((int)pageFormat.getWidth(), (int)pageFormat.getHeight()));
updateUI();
}
private void addBorders(){
if (currentPage == null) return;
if (pageFormat == null) return;
Line border0, border1, border2, border3;
border0 = new Line(this);
border1 = new Line(this);
border2 = new Line(this);
border3 = new Line(this);
border0.setLineWidth(1);
border1.setLineWidth(1);
border2.setLineWidth(1);
border3.setLineWidth(1);
border0.setBorderType(Line.BORDER_UP);
border1.setBorderType(Line.BORDER_LEFT);
border2.setBorderType(Line.BORDER_DOWN);
border3.setBorderType(Line.BORDER_RIGHT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -