Ok so I have a text editor made that can so far create new files and open files using jFileChooser.
What I am trying to do is get the saving of files to work.
Everytime you add or open a few file it adds a new tab to the tabbedpane and the name will be either file 1 etc or the name of the file opened.
When you click the save button the save dialog opens up
int returnVal = fileChooser.showSaveDialog(this);
I want the name on the tab to be inserted to the name of file field.
Also how do I make a file of the current selected tabs textarea? I have tried this but its a no go:
int index = tabbedPane.getSelectedIndex();
Component c = tabbedPane.getComponentAt(index);
JTextArea a = (JTextArea) c;
System.out.println(a.getText());
File file = new File(a.getText());
fileChooser.setSelectedFile(file);
So I need to make a file of the string in the textArea I guess.
Following up #Andrew's answer, here is a snippet illustrating what he meant. I took the liberty to rather use a OutputStreamWriter than a FileWriter because this allows you to choose the charset used to write the file, which is something that you usually want to control and not rely on the "random" default platform charset.
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class TestTextArea {
private JTextArea textArea;
private JButton save;
protected void initUI() {
JFrame frame = new JFrame(TestTextArea.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textArea = new JTextArea(24, 80);
save = new JButton("Save to file");
save.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
saveToFile();
}
});
frame.add(new JScrollPane(textArea));
JPanel buttonPanel = new JPanel();
buttonPanel.add(save);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.setSize(500, 400);
frame.setVisible(true);
}
protected void saveToFile() {
JFileChooser fileChooser = new JFileChooser();
int retval = fileChooser.showSaveDialog(save);
if (retval == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
if (file != null) {
if (!file.getName().toLowerCase().endsWith(".txt")) {
file = new File(file.getParentFile(), file.getName() + ".txt");
}
try {
textArea.write(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
Desktop.getDesktop().open(file);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestTextArea().initUI();
}
});
}
}
An easy way is to use JTextComponent.write(Writer). JTextArea extends JTextComponent.
For the Writer use a FileWriter.
You need to, some how associate the File that was opened with the tab. That way, you can look up the File associated based on the selected tab.
Something like HashMap<Component, File> for example
Related
I am creating a user interface for a pdf reader, and I want to have a list with recent open files. (Not the content of the files, just the name of the file).
From the snap shared, I assume that you are using JFileChooser for your dialog to open file. Hope this helps!
int result = fileChooser.showOpenDialog(panel);
//where panel is an instance of a Component such as JFrame, JDialog or JPanelwhich is parent of the dialog.
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
textArea.setText(selectedFile.getName());
}
The example below uses a JFileChooser with setMultiSelectionEnabled(true) to add() one or more files to a List<File> and update() a JTextArea with the current list. As suggested here, you can use Action to maintain a menu or tool bar of recent files.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
/**
* #see https://stackoverflow.com/a/37153404/230513
* #see https://stackoverflow.com/a/4039359/230513
*/
public class Test {
private final List<File> recentFiles = new ArrayList<>();
private final JTextArea textArea = new JTextArea(12, 12);
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textArea.setBorder(BorderFactory.createTitledBorder("Recent Files"));
f.add(textArea);
JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT));
p.add(new JButton(new AbstractAction("Open") {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = new JFileChooser(".");
jfc.setMultiSelectionEnabled(true);
if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
recentFiles.addAll(Arrays.asList(jfc.getSelectedFiles()));
update();
}
}
}));
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private void update() {
textArea.setText("");
for (File file : recentFiles) {
textArea.append(file.getName() + "\n");
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Test()::display);
}
}
I'm working on this project and I need it run as an applet and an application. This is what I have but I stuck on where to go because I can't find anything on the internet. Are there any resources or does someone have some quick advice to give me?
public class Project extends JApplet {
public void init() {
try {
URL pictureURL = new URL(getDocumentBase(), "sample.jpg");
myPicture = ImageIO.read(pictureURL);
myIcon = new ImageIcon(myPicture);
myLabel = new JLabel(myIcon);
} catch (Exception e) {
e.printStackTrace();
}
add(label, BorderLayout.NORTH);
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
FileInputStream FIS = new FileInputStream("sample.mp3");
player = new Player (FIS);
player.play();
} catch (Exception e1) {
e1.printStackTrace();
}}});
}
public static void main(String args[]) {
JFrame frame = new JFrame("");
frame.getContentPane().add();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea("Bio");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
private Player player;
}
When trying to run something as an applet and as an application, there are several caveats.
Applets have a certain life cycle that must be obeyed. One can add the applet to the content pane of the JFrame and manually call init(), but in general, if the applet expects its start() or stop() methods to be called, things may become tricky...
More importantly: The way how resources are handled is different between applets and applications.
Handling files in applets (e.g. with a FileInputStream) may have security implications, and will plainly not work in some cases - e.g. when the applet is embedded into a website. (Also see What Applets Can and Cannot Do).
Conversely, when running this as an application, calling getDocumentBase() does not make sense. There simply is no "document base" for an application.
Nevertheless, it is possible to write a program that can be shown as an Applet or as an Application. The main difference will then be whether the main JPanel is placed into a JApplet or into a JFrame, and how data is read.
One approach for reading data that works for applets as well as for applications is via getClass().getResourceAsStream("file.txt"), given that the respective file is in the class path.
I hesitated a while, whether I should post an example, targeting the main question, or whether I should modify your code so that it works. I'll do both:
Here is an example that can be executed as an Applet or as an Application. It will read and display a "sample.jpg". (This file is currently basically expected to be "in the same directory as the .class-file". More details about resource handling, classpaths and stream handling are beyond the scope of this answer)
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class AppletOrApplicationExample extends JApplet
{
#Override
public void init()
{
add(new AppletOrApplicationMainComponent());
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
frame.getContentPane().add(new AppletOrApplicationMainComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class AppletOrApplicationMainComponent extends JPanel
{
public AppletOrApplicationMainComponent()
{
super(new BorderLayout());
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
add(new JLabel("Resource not found"), BorderLayout.NORTH);
}
else
{
try
{
BufferedImage image = ImageIO.read(stream);
add(new JLabel(new ImageIcon(image)), BorderLayout.NORTH);
}
catch (IOException e1)
{
add(new JLabel("Could not load image"), BorderLayout.NORTH);
}
}
JTextArea textArea = new JTextArea("Text...");
add(textArea, BorderLayout.CENTER);
JButton button = new JButton("Button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
doSomething();
}
});
add(button, BorderLayout.SOUTH);
}
private void doSomething()
{
System.out.println("Button was clicked");
}
}
And here is something that is still a bit closer to your original code. However, I'd strongly recommend to factor out the actual application logic as far as possible. For example, your main GUI component should then not be the applet itself, but a JPanel. Resources should not be read directly via FileInputStreams or URLs from the document base, but only from InputStreams. This is basically the code that you posted, with the fewest modifications that are necessary to get it running as an applet or an application:
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Module5Assignment2 extends JApplet
{
public void init()
{
try
{
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
System.out.println("Resource not found");
}
else
{
myPicture = ImageIO.read(stream);
icon = new ImageIcon(myPicture);
label = new JLabel(icon);
add(label, BorderLayout.NORTH);
}
}
catch (Exception e)
{
e.printStackTrace();
}
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
FileInputStream FIS = new FileInputStream("sample.mp3");
// player = new Player (FIS);
// player.play();
}
catch (Exception e1)
{
e1.printStackTrace();
}
}
});
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
// ******PRETTY SURE I NEED TO ADD SOMETHING HERE*************
Module5Assignment2 contents = new Module5Assignment2();
frame.getContentPane().add(contents);
contents.init();
// *************************************************************
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea(
"This is the bio of Christian Sprague; he doesn't like typing things.");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
// private Player player;
}
i am making a text editor, and this is the basic version of my code. I used UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); to make the whole thing look like the platform I am using, but the JFileChooser save is always the java look and feel. Can anybody help? I might be putting it in the wrong spot, but I don't know where
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
#SuppressWarnings("serial")
public class TextEditor extends JPanel {
static Container pane;
static Container paneText;
static BasicFrame frame;
static JTextArea textArea;
static JScrollPane areaScrollPane;
static FileFilter txtFile;
static JFileChooser save = new FileChooser(System.getProperty("user.home//documents"));
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException, IOException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
frame = BasicFrame.getInstance();
pane = frame.getContentPane();
paneText = new JPanel();
textArea = new JTextArea();
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
areaScrollPane = new JScrollPane(textArea);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(250, 250));
int hGap = 10;
int vGap = 20;
pane.setLayout(new FlowLayout(FlowLayout.LEFT, hGap, vGap));
Action SaveAs = new SaveAs("Save File", "Writes the text file");
JButton one = new JButton(SaveAs);
one.addActionListener(null);
txtFile = new FileNameExtensionFilter("Text File (.txt)", "txt");
save.addChoosableFileFilter(txtFile);
save.setFileFilter(txtFile);
save.setAcceptAllFileFilterUsed(true);
pane.add(areaScrollPane);
pane.add(one);
pane.add(paneText);
paneText.setLayout(new BoxLayout(paneText, BoxLayout.Y_AXIS));
frame.setSize(450, 320);
frame.setVisible(true);
}
static class SaveAs extends AbstractAction {
public SaveAs(String text, String desc) {
super(text);
putValue(SHORT_DESCRIPTION, desc);
}
public void actionPerformed(ActionEvent e) {
save.setFileHidingEnabled(false);
save.setApproveButtonText("Save");
save.setSelectedFile(new File("new 1"));
int actionDialog = save.showSaveDialog(null);
if (actionDialog != JFileChooser.APPROVE_OPTION) {
return;
} else {
log("Done!", true);
}
String name = save.getSelectedFile().getAbsolutePath();
if (!name.endsWith(".txt") && save.getFileFilter() == txtFile) {
name += ".txt";
}
BufferedWriter outFile = null;
try {
outFile = new BufferedWriter(new FileWriter(name));
textArea.write(outFile);
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (outFile != null) {
try {
outFile.close();
} catch (IOException ioee) {
}
}
}
}
private void log(String msg, boolean remove) {
JLabel label1;
label1 = new JLabel(msg);
if (remove) {
paneText.removeAll();
}
paneText.add(label1);
paneText.validate();
pane.validate();
new Thread() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
paneText.removeAll();
paneText.validate();
pane.validate();
}
}.start();
}
}
}
The JFileChooser in your code is static and therefore is instantiated before the Look and Feel is set in main.
Set the Look and Feel before instantiation. So, both in a static block since your JFileChooser is static.
...
static FileFilter txtFile;
static JFileChooser save;
static {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException |
InstantiationException |
IllegalAccessException |
UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
save = new JFileChooser(System.getProperty("user.home//documents"));
}
public static void main(String[] args) {
frame = new JFrame();
pane = frame.getContentPane();
...
...
Instead of System.getProperty("user.home//documents"), type (System.getProperty("user.home") + "/documents") (Assuming your documents folder is called "documents"). The former would return null, setting the JFileChooser's location to its default -- the user's home directory.
This is because "user.home//documents" is not a defined key for System.getProperty(), while "user.home" is.
You should also set your JFileChooser to a new JFileChooser(<path>) rather than a new FileChooser(<path>)
The LookAndFeel declaration must be made before the initialization of the Object, otherwise the object won't take on those LookAndFeel properties.
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
THEN
save = new FileChooser(System.getProperty("user.home//documents"));
I am creating a program which allows the user to enter data and then click a button to view said data. On the first frame I want the user to select an item from a ComboBox and when they click a button it takes the selected item from the ComboBox and enters it as a parameter for another method which will bring up data from a file (this method isn't yet complete).
The code I have so far is as follows:
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SpringLayout;
public class Main implements ActionListener{
static JButton ViewData = new JButton("View Data");
static JButton AddItem = new JButton("Add Item");
String Item = null;
public static void main(String[]args){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new Main();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public Main() throws IOException{
//Populating ComboBox
String FilePath = "C:/Users/Harry/AS Computing/CWTreasurers/src/ItemList";
BufferedReader input = new BufferedReader(new FileReader(FilePath));
ArrayList<String> strings = new ArrayList<String>();
try {
String line = null;
while (( line = input.readLine()) != null){
strings.add(line);
}//End While
}//End Try
catch (FileNotFoundException e) {
System.err.println("Error, file " + FilePath + " didn't exist.");
}//End catch
finally {
input.close();
}//end Finally
String[] lineArray = strings.toArray(new String[]{});
JComboBox ChooseItems = new JComboBox(lineArray);
//End populating ComboBox
JFrame frame = new JFrame("CharityWeekTreasury");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//Sets Default properties of the window
Container ContentPane = frame.getContentPane();
SpringLayout layout = new SpringLayout();
ContentPane.setLayout(layout);
//Defines the container for all objects and the layout
ContentPane.add(ChooseItems);
ContentPane.add(ViewData);
ContentPane.add(AddItem);
ViewData.addActionListener(this);
AddItem.addActionListener(this);
//Adds Objects to window
layout.putConstraint(SpringLayout.WEST,ChooseItems,5,SpringLayout.WEST,ContentPane);
layout.putConstraint(SpringLayout.NORTH,ChooseItems,5,SpringLayout.NORTH,ContentPane);
layout.putConstraint(SpringLayout.WEST,ViewData,5,SpringLayout.EAST,ChooseItems);
layout.putConstraint(SpringLayout.NORTH,ViewData,5,SpringLayout.NORTH,ContentPane);
layout.putConstraint(SpringLayout.WEST,AddItem,5,SpringLayout.EAST,ViewData);
layout.putConstraint(SpringLayout.NORTH,AddItem,5,SpringLayout.NORTH,ContentPane);
layout.putConstraint(SpringLayout.EAST,ContentPane,5,SpringLayout.EAST,AddItem);
layout.putConstraint(SpringLayout.SOUTH,ContentPane,5,SpringLayout.SOUTH,ChooseItems);
//Sets Positioning of objects relative to each other
frame.pack();
frame.setVisible(true);
//Makes frame visible
}//End Window
public void actionPerformed(ActionEvent e) {
JButton b = (JButton)e.getSource();
if(b.equals(ViewData)){
Item = ChooseItems.getSelectedItem();
ViewData view = new ViewData(Item);
}else if(b.equals(AddItem)){
new AddItem();
}
}
}
ViewData is both a button and the name of another class in the project, the main error is that the line
Item = ChooseItems.getSelectedItem();
Doesn't seem to work, I believe this to be due to the positioning of where ChooseItems is declared, this meaning that there is no ChooseItems to get a selected item of.
Any help is much appreciated. Thanks.
I faced a problem that the typed data can not be persistent. I want to store java Swing GUI to XML file and reuse them latter. Now I store the GUI successfully. But after I type some data into the textfield. The typed data can not be encoded into XML file. Could you help me store both the GUI and the typed content? Below is the code using javabeans XMLencoder:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import java.beans.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class ResourceName extends JFrame implements ActionListener{
static JFileChooser chooser;
JButton save,load;
JTextField tf;
static JFrame frame;
public ResourceName(){
chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
frame = new JFrame("ResourceName");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
save = new JButton("Save");
save.setActionCommand("Save");
save.addActionListener(this);
load = new JButton("Load");
load.setActionCommand("Load");
load.addActionListener(this);
tf = new JTextField(10);
frame.add(save);
frame.add(tf);
frame.add(load);
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if((e.getActionCommand()).equals("Save"))
{
save();
}else if((e.getActionCommand()).equals("Load"))
{
load();
}
}
public void save()
{
if(chooser.showSaveDialog(null)==JFileChooser.APPROVE_OPTION)
{
try{
File file = chooser.getSelectedFile();
XMLEncoder encoder = new XMLEncoder(new FileOutputStream(file));
encoder.writeObject(frame);
encoder.close();
}
catch(IOException e)
{
JOptionPane.showMessageDialog(null, e);
}
}
}
public void load()
{
//show file chooser dialog
int r = chooser.showOpenDialog(null);
// if file selected, open
if(r == JFileChooser.APPROVE_OPTION)
{
try
{
File file = chooser.getSelectedFile();
XMLDecoder decoder = new XMLDecoder(new FileInputStream(file));
decoder.readObject();
decoder.close();
}
catch(IOException e)
{
JOptionPane.showMessageDialog(null, e);
}
}
}
public static void main(String[] args) {
ResourceName test = new ResourceName();
}
}
Please help me solve this problem. Many Thanks!
it may be that the text property, is transient, this means it won't be saved to the output automatically, by an ObjectOutputStream. You'll probably have to explicitly write that field.