Original sources, as-is

This commit is contained in:
Imbus 2024-05-11 13:02:50 +02:00
parent a1ad9d1728
commit 9e257321ab
40 changed files with 1186 additions and 0 deletions

View file

@ -0,0 +1,18 @@
package xl.expr;
class Add extends BinaryExpr {
Add(Expr expr1, Expr expr2) {
super(expr1, expr2);
precedence1 = 0;
precedence2 = 0;
}
public double op(double op1, double op2) {
return op1 + op2;
}
protected String opString() {
return "+";
}
}

View file

@ -0,0 +1,37 @@
package xl.expr;
abstract class BinaryExpr extends Expr {
private Expr expr1;
private Expr expr2;
protected int precedence1;
protected int precedence2;
protected BinaryExpr(Expr expr1, Expr expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
protected abstract double op(double op1, double op2);
protected abstract String opString();
public String toString(int prec) {
StringBuilder builder = new StringBuilder();
boolean parentheses = prec > precedence1;
if (parentheses) {
builder.append('(');
}
builder.append(expr1.toString(precedence1));
builder.append(opString());
builder.append(expr2.toString(precedence2));
if (parentheses) {
builder.append(')');
}
return builder.toString();
}
public double value(Environment env) {
return op(expr1.value(env), expr2.value(env));
}
}

View file

@ -0,0 +1,21 @@
package xl.expr;
import xl.util.XLException;
class Div extends BinaryExpr {
Div(Expr expr1, Expr expr2) {
super(expr1, expr2);
precedence1 = 1;
precedence2 = 2;
}
public double op(double op1, double op2) {
if (op2 != 0) return op1 / op2;
else throw new XLException("division by zero");
}
protected String opString() {
return "/";
}
}

View file

@ -0,0 +1,6 @@
package xl.expr;
public interface Environment {
public double value(String name);
}

View file

@ -0,0 +1,38 @@
package xl.expr;
/**
* An <code>Expr</code> object represents a real valued expression that may contain variables. The
* value of a variable is obtained from an <code>Environment</code> object by specifying the name of
* the variable.
*
* @see Environment
* @author Lennart Andersson
*/
public abstract class Expr {
/**
* The <code>toString</code> method returns a <code>String</code> representation of this
* expression without unnecessary parentheses.
*
* @return the <code>String</code> representation of this expression.
*/
public String toString() {
return toString(0);
}
/*
* toString(prec) returns a string representation of this expression without
* unnecessary parentheses. The prec argument specifies the precedence level
* enclosing expression and is used to control the precedence of
* parentheses.
*/
public abstract String toString(int prec);
/**
* The <code>value</code> method returns the value of this expression.
*
* @param env is the <code>Environment</code> containing the values of variables.
* @return the <code>double</code> value of this expression.
*/
public abstract double value(Environment env);
}

View file

@ -0,0 +1,136 @@
package xl.expr;
import java.io.IOException;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.regex.Pattern;
import xl.util.XLException;
/**
* An <code>ExprParser</code> object is a parser provides a factory method for building <code>Expr
* </code> objects from text representations of arithmetic expressions. The text containing the
* expression should adhere to the following grammar.
*
* <pre>
*
*
*
* expr ::= term {addop term}
* term ::= factor {mulop factor}
* factor ::= number | variable | &quot;(&quot; expr &quot;)&quot;
* addop ::= &quot;+&quot; | &quot;-&quot;
* mulop ::= &quot;*&quot; | &quot;/&quot;
*
*
*
* </pre>
*
* where <code>number</code> is an unsigned number according to <code>StreamTokenizer</code> and
* <code>variable</code> is a string of letters and digits. The first character must be a letter.
*
* @see Expr
* @see StreamTokenizer
* @author Lennart Andersson
*/
public class ExprParser {
private int token;
private StreamTokenizer tokenizer;
/**
* The <code>build</code> method returns an <code>Expr</code> representation of the expression
* provided by <code>reader</code>.
*
* @param reader a <code>Reader</code> provided the string to be parsed.
* @return an <code>Expr</code> representation of the string.
* @exception IOException if the <code>reader</code> does not deliver data.
* @exception ExprParserException if the reader input violates the grammar.
*/
public Expr build(Reader reader) throws IOException {
tokenizer = new StreamTokenizer(reader);
tokenizer.ordinaryChar('-');
tokenizer.ordinaryChar('/');
token = tokenizer.nextToken();
Expr e = expr();
if (token == StreamTokenizer.TT_EOF) return e;
else throw new XLException("trailing garbage");
}
/**
* The <code>build</code> method returns an <code>Expr</code> representation of the expression
* provided by the <code>input</code> string.
*
* @param input the <code>String</code> to be parsed.
* @return an <code>Expr</code> representation of the string.
* @exception IOException if the <code>input</code> does not deliver data.
* @exception XLException if the input violates the grammar.
*/
public Expr build(String input) throws IOException {
return build(new StringReader(input));
}
private Expr expr() throws IOException {
Expr result, term;
result = term();
while (token == '+' || token == '-') {
int op = token;
token = tokenizer.nextToken();
term = term();
switch (op) {
case '+':
result = new Add(result, term);
break;
case '-':
result = new Sub(result, term);
break;
}
}
return result;
}
private Expr factor() throws IOException {
Expr e;
switch (token) {
case '(':
token = tokenizer.nextToken();
e = expr();
if (token != ')') throw new XLException("expecting \")\", found: " + token);
token = tokenizer.nextToken();
return e;
case StreamTokenizer.TT_NUMBER:
double x = tokenizer.nval;
token = tokenizer.nextToken();
return new Num(x);
case StreamTokenizer.TT_WORD:
String address = tokenizer.sval.toUpperCase();
if (!Pattern.matches("[A-Z][0-9]+", address))
throw new XLException("illegal address: " + address);
token = tokenizer.nextToken();
return new Variable(address);
case StreamTokenizer.TT_EOF:
throw new XLException("unexpected end of text");
default:
throw new XLException("unexpected " + (char) token);
}
}
private Expr term() throws IOException {
Expr result, factor;
result = factor();
while (token == '*' || token == '/') {
int op = token;
token = tokenizer.nextToken();
factor = factor();
switch (op) {
case '*':
result = new Mul(result, factor);
break;
case '/':
result = new Div(result, factor);
break;
}
}
return result;
}
}

View file

@ -0,0 +1,18 @@
package xl.expr;
class Mul extends BinaryExpr {
Mul(Expr expr1, Expr expr2) {
super(expr1, expr2);
precedence1 = 1;
precedence2 = 1;
}
public double op(double op1, double op2) {
return op1 * op2;
}
protected String opString() {
return "*";
}
}

View file

@ -0,0 +1,21 @@
package xl.expr;
import xl.util.NumberAdjustment;
class Num extends Expr {
private static NumberAdjustment adjustment = new NumberAdjustment(0, 2);
private double value;
Num(double value) {
this.value = value;
}
public String toString(int prec) {
return adjustment.right(value);
}
public double value(Environment env) {
return value;
}
}

View file

@ -0,0 +1,18 @@
package xl.expr;
class Sub extends BinaryExpr {
Sub(Expr expr1, Expr expr2) {
super(expr1, expr2);
precedence1 = 0;
precedence2 = 1;
}
public double op(double op1, double op2) {
return op1 - op2;
}
protected String opString() {
return "-";
}
}

View file

@ -0,0 +1,30 @@
package xl.expr;
import java.io.IOException;
public class TestExpr {
public static void main(String[] args) {
ExprParser parser = new ExprParser();
try {
Expr expr = parser.build("1+2*3");
System.out.println(expr);
System.out.println(expr.value(null));
expr = parser.build("A3+A2*A1");
Environment env =
new Environment() {
public double value(String name) {
if (name.equals("A3")) return 1;
if (name.equals("A2")) return 2;
if (name.equals("A1")) return 3;
System.out.println(name + " is undefined");
return 0;
}
};
System.out.println(expr);
System.out.println(expr.value(env));
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}

View file

@ -0,0 +1,18 @@
package xl.expr;
class Variable extends Expr {
private String name;
Variable(String name) {
this.name = name;
}
public String toString(int prec) {
return name.toString();
}
public double value(Environment env) {
return env.value(name);
}
}

View file

@ -0,0 +1,13 @@
package xl.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JPanel;
public class BorderPanel extends JPanel {
protected BorderPanel() {
super(new BorderLayout(2, 2));
setBackground(Color.BLACK);
}
}

View file

@ -0,0 +1,22 @@
package xl.gui;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
public class ColoredLabel extends JLabel {
public ColoredLabel(String text) {
this(text, Color.WHITE, SwingConstants.LEFT);
}
public ColoredLabel(String text, Color color) {
this(text, color, SwingConstants.LEFT);
}
public ColoredLabel(String text, Color color, int alignment) {
super(text, alignment);
setBackground(color);
setOpaque(true);
}
}

View file

@ -0,0 +1,10 @@
package xl.gui;
import java.awt.Color;
public class CurrentLabel extends ColoredLabel {
public CurrentLabel() {
super("A1", Color.WHITE);
}
}

View file

@ -0,0 +1,11 @@
package xl.gui;
import java.awt.Color;
import javax.swing.JTextField;
public class Editor extends JTextField {
public Editor() {
setBackground(Color.WHITE);
}
}

View file

@ -0,0 +1,13 @@
package xl.gui;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JPanel;
public class GridPanel extends JPanel {
public GridPanel(int rows, int columns) {
super(new GridLayout(rows, columns, 2, 2));
setBackground(Color.BLACK);
}
}

View file

@ -0,0 +1,15 @@
package xl.gui;
import static java.awt.Color.LIGHT_GRAY;
import static javax.swing.SwingConstants.RIGHT;
class RowLabels extends GridPanel {
RowLabels(int rows) {
super(rows + 1, 1);
add(new ColoredLabel("", LIGHT_GRAY, RIGHT));
for (int i = 1; i <= rows; i++) {
add(new ColoredLabel(String.valueOf(i), LIGHT_GRAY, RIGHT));
}
}
}

View file

@ -0,0 +1,12 @@
package xl.gui;
import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.WEST;
public class SheetPanel extends BorderPanel {
public SheetPanel(int rows, int columns) {
add(WEST, new RowLabels(rows));
add(CENTER, new SlotLabels(rows, columns));
}
}

View file

@ -0,0 +1,10 @@
package xl.gui;
import java.awt.Color;
public class SlotLabel extends ColoredLabel {
public SlotLabel() {
super(" ", Color.WHITE, RIGHT);
}
}

View file

@ -0,0 +1,28 @@
package xl.gui;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingConstants;
public class SlotLabels extends GridPanel {
private List<SlotLabel> labelList;
public SlotLabels(int rows, int cols) {
super(rows + 1, cols);
labelList = new ArrayList<SlotLabel>(rows * cols);
for (char ch = 'A'; ch < 'A' + cols; ch++) {
add(new ColoredLabel(Character.toString(ch), Color.LIGHT_GRAY, SwingConstants.CENTER));
}
for (int row = 1; row <= rows; row++) {
for (char ch = 'A'; ch < 'A' + cols; ch++) {
SlotLabel label = new SlotLabel();
add(label);
labelList.add(label);
}
}
SlotLabel firstLabel = labelList.get(0);
firstLabel.setBackground(Color.YELLOW);
}
}

View file

@ -0,0 +1,16 @@
package xl.gui;
import java.awt.Color;
import java.util.Observable;
import java.util.Observer;
public class StatusLabel extends ColoredLabel implements Observer {
public StatusLabel() {
super("", Color.WHITE);
}
public void update(Observable observable, Object object) {
setText("");
}
}

View file

@ -0,0 +1,12 @@
package xl.gui;
import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.WEST;
public class StatusPanel extends BorderPanel {
protected StatusPanel(StatusLabel statusLabel) {
add(WEST, new CurrentLabel());
add(CENTER, statusLabel);
}
}

View file

@ -0,0 +1,49 @@
package xl.gui;
import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.NORTH;
import static java.awt.BorderLayout.SOUTH;
import javax.swing.JFrame;
import javax.swing.JPanel;
import xl.gui.menu.XLMenuBar;
public class XL extends JFrame {
private static final int ROWS = 10, COLUMNS = 8;
private XLCounter counter;
private StatusLabel statusLabel = new StatusLabel();
private XLList xlList;
public XL(XL oldXL) {
this(oldXL.xlList, oldXL.counter);
}
public XL(XLList xlList, XLCounter counter) {
super("Untitled-" + counter);
this.xlList = xlList;
this.counter = counter;
xlList.add(this);
counter.increment();
JPanel statusPanel = new StatusPanel(statusLabel);
JPanel sheetPanel = new SheetPanel(ROWS, COLUMNS);
Editor editor = new Editor();
add(NORTH, statusPanel);
add(CENTER, editor);
add(SOUTH, sheetPanel);
setJMenuBar(new XLMenuBar(this, xlList, statusLabel));
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
}
public void rename(String title) {
setTitle(title);
xlList.setChanged();
}
public static void main(String[] args) {
new XL(new XLList(), new XLCounter());
}
}

View file

@ -0,0 +1,14 @@
package xl.gui;
public class XLCounter {
private int counter;
public void increment() {
counter++;
}
public String toString() {
return Integer.toString(counter);
}
}

View file

@ -0,0 +1,40 @@
package xl.gui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;
public class XLList extends Observable implements Iterable<XL> {
private List<XL> list = new ArrayList<XL>();
public void add(XL xl) {
list.add(xl);
setChanged();
notifyObservers();
}
public boolean isEmpty() {
return list.isEmpty();
}
public Iterator<XL> iterator() {
return list.iterator();
}
public XL last() {
return list.get(list.size() - 1);
}
public void remove(XL xl) {
list.remove(xl);
setChanged();
notifyObservers();
}
public void setChanged() {
super.setChanged();
notifyObservers();
}
}

View file

@ -0,0 +1,17 @@
package xl.gui.menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
class ClearAllMenuItem extends JMenuItem implements ActionListener {
public ClearAllMenuItem() {
super("Clear all");
addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// TODO
}
}

View file

@ -0,0 +1,17 @@
package xl.gui.menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
class ClearMenuItem extends JMenuItem implements ActionListener {
public ClearMenuItem() {
super("Clear");
addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// TODO
}
}

View file

@ -0,0 +1,30 @@
package xl.gui.menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import xl.gui.XL;
import xl.gui.XLList;
class CloseMenuItem extends JMenuItem implements ActionListener {
private XL xl;
private XLList xlList;
public CloseMenuItem(XL xl, XLList xlList) {
super("Close");
this.xl = xl;
this.xlList = xlList;
addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
xlList.remove(xl);
xl.dispose();
if (xlList.isEmpty()) {
System.exit(0);
} else {
xlList.last().toFront();
}
}
}

View file

@ -0,0 +1,21 @@
package xl.gui.menu;
import java.io.FileNotFoundException;
import javax.swing.JFileChooser;
import xl.gui.StatusLabel;
import xl.gui.XL;
class LoadMenuItem extends OpenMenuItem {
public LoadMenuItem(XL xl, StatusLabel statusLabel) {
super(xl, statusLabel, "Load");
}
protected void action(String path) throws FileNotFoundException {
// TODO
}
protected int openDialog(JFileChooser fileChooser) {
return fileChooser.showOpenDialog(xl);
}
}

View file

@ -0,0 +1,21 @@
package xl.gui.menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import xl.gui.XL;
class NewMenuItem extends JMenuItem implements ActionListener {
private XL xl;
public NewMenuItem(XL xl) {
super("New");
this.xl = xl;
addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
new XL(xl);
}
}

View file

@ -0,0 +1,45 @@
package xl.gui.menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import xl.gui.StatusLabel;
import xl.gui.XL;
public abstract class OpenMenuItem extends JMenuItem implements ActionListener {
protected StatusLabel statusLabel;
protected XL xl;
protected OpenMenuItem(XL xl, StatusLabel statusLabel, String title) {
super(title);
this.xl = xl;
this.statusLabel = statusLabel;
addActionListener(this);
}
protected abstract void action(String path) throws FileNotFoundException;
public void actionPerformed(ActionEvent event) {
JFileChooser fileChooser = new JFileChooser(".");
FileFilter filter = new FileNameExtensionFilter("XL files", "xl");
fileChooser.setFileFilter(filter);
int option = openDialog(fileChooser);
if (option == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
try {
action(file.toString());
xl.rename(file.getName());
} catch (FileNotFoundException e) {
statusLabel.setText(e.getMessage());
}
}
}
protected abstract int openDialog(JFileChooser fileChooser);
}

View file

@ -0,0 +1,21 @@
package xl.gui.menu;
import java.io.FileNotFoundException;
import javax.swing.JFileChooser;
import xl.gui.StatusLabel;
import xl.gui.XL;
class SaveMenuItem extends OpenMenuItem {
public SaveMenuItem(XL xl, StatusLabel statusLabel) {
super(xl, statusLabel, "Save");
}
protected void action(String path) throws FileNotFoundException {
// TODO
}
protected int openDialog(JFileChooser fileChooser) {
return fileChooser.showSaveDialog(xl);
}
}

View file

@ -0,0 +1,26 @@
package xl.gui.menu;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JMenu;
import xl.gui.XL;
import xl.gui.XLList;
public class WindowMenu extends JMenu implements Observer {
private XLList xlList;
public WindowMenu(XLList xlList) {
super("Window");
this.xlList = xlList;
xlList.addObserver(this);
update(null, null);
}
public void update(Observable observable, Object object) {
removeAll();
for (XL xl : xlList) {
add(new WindowMenuItem(xl));
}
}
}

View file

@ -0,0 +1,21 @@
package xl.gui.menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import xl.gui.XL;
class WindowMenuItem extends JMenuItem implements ActionListener {
private XL xl;
public WindowMenuItem(XL xl) {
super(xl.getTitle());
this.xl = xl;
addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
xl.toFront();
}
}

View file

@ -0,0 +1,24 @@
package xl.gui.menu;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import xl.gui.StatusLabel;
import xl.gui.XL;
import xl.gui.XLList;
public class XLMenuBar extends JMenuBar {
public XLMenuBar(XL xl, XLList xlList, StatusLabel statusLabel) {
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
file.add(new SaveMenuItem(xl, statusLabel));
file.add(new LoadMenuItem(xl, statusLabel));
file.add(new NewMenuItem(xl));
file.add(new CloseMenuItem(xl, xlList));
edit.add(new ClearMenuItem());
edit.add(new ClearAllMenuItem());
add(file);
add(edit);
add(new WindowMenu(xlList));
}
}

View file

@ -0,0 +1,134 @@
package xl.util;
/**
* Adjustment.java Created: Tue Oct 24 2005
*
* @author Lennart Andersson
* @version 0.1
*/
/** Adjustment is a class for adjusting string representations of values within a String. */
public class Adjustment {
private int width;
/**
* Creates an adjustment.
*
* @param width is the number of positions for the result. If the width is insufficient extra
* positions are added.
*/
public Adjustment(int width) {
this.width = width;
}
/**
* Returns a centered String.
*
* @param s is the string to adjust.
*/
public String center(String s) {
StringBuilder builder = new StringBuilder(width);
int fill = width - s.length();
for (int i = 0; i < fill / 2; i++) {
builder.append(' ');
}
builder.append(s);
for (int i = 0; i < fill - fill / 2; i++) {
builder.append(' ');
}
return builder.toString();
}
/**
* Returns a left adjusted String.
*
* @param s is the string to adjust.
*/
public String left(String s) {
StringBuilder builder = new StringBuilder(width);
builder.append(s);
int fill = width - s.length();
for (int i = 0; i < fill; i++) {
builder.append(' ');
}
return builder.toString();
}
/**
* Returns a right adjusted String.
*
* @param b is the value to adjust.
*/
public String right(boolean b) {
return right(String.valueOf(b));
}
/**
* Returns a right adjusted String.
*
* @param c is the value to adjust.
*/
public String right(char c) {
return right(String.valueOf(c));
}
/**
* Returns a right adjusted String.
*
* @param number is the value to adjust.
*/
public String right(double number) {
return right(String.valueOf(number));
}
/**
* Returns a right adjusted String.
*
* @param number is the value to adjust.
*/
public String right(float number) {
return right(String.valueOf(number));
}
/**
* Returns a right adjusted String.
*
* @param number is the value to adjust.
*/
public String right(int number) {
return right(String.valueOf(number));
}
/**
* Returns a right adjusted String.
*
* @param number is the value to adjust.
*/
public String right(long number) {
return right(String.valueOf(number));
}
/**
* Returns a right adjusted String.
*
* @param item is the value to adjust.
*/
public String right(Object item) {
return right(String.valueOf(item));
}
/**
* Returns a right adjusted String.
*
* @param s is the string to adjust.
*/
public String right(String s) {
StringBuilder builder = new StringBuilder(width);
int fill = width - s.length();
for (int i = 0; i < fill; i++) {
builder.append(' ');
}
builder.append(s);
return builder.toString();
}
}

View file

@ -0,0 +1,123 @@
package xl.util;
/**
* NumberAdjustment.java Created: Mon OTue 24 2005
*
* @author Lennart Andersson
* @version 0.1
*/
/**
* Adjustment is a class for adjusting string representations of numerical values within a String.
*/
public class NumberAdjustment extends Adjustment {
private static final double log10 = Math.log(10.0);
private int decimals;
private int exponent;
/**
* Creates an adjustment for numbers.
*
* @param width is the number of positions for the result. If the width is insufficient extra
* positions are added.
* @param decimals is the number of decimals in the result.
*/
public NumberAdjustment(int width, int decimals) {
super(width);
this.decimals = decimals;
}
/**
* Creates an adjustment for numbers with an exponent field.
*
* @param width is the number of positions for the result. If the width is insufficient extra
* positions are added.
* @param decimals is the number of positions for the decimals.
* @param exponent is the number of positions for the exponent including the letter E. If the
* width is unsufficient extra positions are added.
*/
public NumberAdjustment(int width, int decimals, int exponent) {
this(width, decimals);
this.exponent = exponent;
}
private StringBuilder fillZero(int exp) {
StringBuilder builder = new StringBuilder();
int length = exponent;
if (exp < 0) {
builder.append('-');
exp = -exp;
length = exponent - 1;
}
String s = String.valueOf(exp);
for (int i = s.length(); i < length; i++) {
builder.append('0');
}
return builder.append(s);
}
private StringBuilder format(double number) {
StringBuilder builder = new StringBuilder();
long intpart = (long) number;
builder.append(intpart);
double fraction = number - intpart;
if (decimals > 0) {
builder.append('.');
}
for (int i = 0; i < decimals; i++) {
fraction *= 10;
int d = (int) fraction;
builder.append((char) (d + '0'));
fraction = fraction - d;
}
return builder;
}
/**
* Returns a right adjusted String.
*
* @param number is the value to adjust.
*/
public String right(double number) {
StringBuilder builder = new StringBuilder();
boolean negative = number < 0;
if (negative) {
number = -number;
builder.append('-');
}
if (exponent > 0) {
if (number == 0.0) return right(format(0.0) + "E" + fillZero(0));
int exp = (int) Math.floor((Math.log(number) / log10));
number /= Math.pow(10.0, exp);
number += 0.5 * Math.pow(10.0, -decimals);
if (number >= 10.0) {
number /= 10.0;
exp++;
}
builder.append(format(number)).append('E').append(fillZero(exp));
} else {
number += 0.5 * Math.pow(10.0, -decimals);
builder.append(format(number));
}
return right(builder.toString());
}
/**
* Returns a right adjusted String.
*
* @param number is the value to adjust.
*/
public String right(float number) {
return right((double) number);
}
public static void main(String[] args) {
Adjustment adjustment = new NumberAdjustment(10, 2, 2);
System.out.println("0123456789");
System.out.println(adjustment.right(-0.0000000000000000000000000));
float value = (float) (1 / 3.0);
System.out.println(adjustment.right(value));
adjustment = new Adjustment(12);
System.out.println(adjustment.right(value));
}
}

View file

@ -0,0 +1,27 @@
package xl.util;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Map;
// TODO move to another package
public class XLBufferedReader extends BufferedReader {
public XLBufferedReader(String name) throws FileNotFoundException {
super(new FileReader(name));
}
// TODO Change Object to something appropriate
public void load(Map<String, Object> map) {
try {
while (ready()) {
String string = readLine();
int i = string.indexOf('=');
// TODO
}
} catch (Exception e) {
throw new XLException(e.getMessage());
}
}
}

View file

@ -0,0 +1,8 @@
package xl.util;
public class XLException extends RuntimeException {
public XLException(String message) {
super(message);
}
}

View file

@ -0,0 +1,25 @@
package xl.util;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Map.Entry;
import java.util.Set;
// TODO move to another package
public class XLPrintStream extends PrintStream {
public XLPrintStream(String fileName) throws FileNotFoundException {
super(fileName);
}
// TODO Change Object to something appropriate
public void save(Set<Entry<String, Object>> set) {
for (Entry<String, Object> entry : set) {
print(entry.getKey());
print('=');
println(entry.getValue());
}
flush();
close();
}
}